Преглед изворни кода

added position absolute and some flexbox so I could remov changes in display and setTimeout, added tests and types, did some renaming

Patrick O'Carroll пре 7 година
родитељ
комит
f4ab432542

+ 1 - 1
public/app/containers/Teams/TeamList.tsx

@@ -55,7 +55,7 @@ export class TeamList extends React.Component<Props, any> {
           <a href={teamUrl}>{team.memberCount}</a>
         </td>
         <td className="text-right">
-          <DeleteButton confirmDelete={() => this.deleteTeam(team)} />
+          <DeleteButton onConfirmDelete={() => this.deleteTeam(team)} />
         </td>
       </tr>
     );

+ 44 - 0
public/app/core/components/DeleteButton/DeleteButton.jest.tsx

@@ -0,0 +1,44 @@
+import React from 'react';
+import DeleteButton from './DeleteButton';
+import { shallow } from 'enzyme';
+
+describe('DeleteButton', () => {
+  let wrapper;
+  let deleted;
+
+  beforeAll(() => {
+    deleted = false;
+
+    function deleteItem() {
+      deleted = true;
+    }
+    wrapper = shallow(<DeleteButton onConfirmDelete={() => deleteItem()} />);
+  });
+
+  it('should show confirm delete when clicked', () => {
+    expect(wrapper.state().showConfirm).toBe(false);
+    wrapper.find('.delete-button').simulate('click');
+    expect(wrapper.state().showConfirm).toBe(true);
+  });
+
+  it('should hide confirm delete when clicked', () => {
+    wrapper.find('.delete-button').simulate('click');
+    expect(wrapper.state().showConfirm).toBe(true);
+    wrapper
+      .find('.confirm-delete')
+      .find('.btn')
+      .at(0)
+      .simulate('click');
+    expect(wrapper.state().showConfirm).toBe(false);
+  });
+
+  it('should show confirm delete when clicked', () => {
+    expect(deleted).toBe(false);
+    wrapper
+      .find('.confirm-delete')
+      .find('.btn')
+      .at(1)
+      .simulate('click');
+    expect(deleted).toBe(true);
+  });
+});

+ 35 - 47
public/app/core/components/DeleteButton/DeleteButton.tsx

@@ -1,73 +1,61 @@
-import React, { Component } from 'react';
+import React, { PureComponent } from 'react';
 
-export default class DeleteButton extends Component<any, any> {
-  state = {
-    deleteButton: 'delete-button--show',
-    confirmSpan: 'confirm-delete--removed',
+export interface DeleteButtonProps {
+  onConfirmDelete();
+}
+
+export interface DeleteButtonStates {
+  showConfirm: boolean;
+}
+
+export default class DeleteButton extends PureComponent<DeleteButtonProps, DeleteButtonStates> {
+  state: DeleteButtonStates = {
+    showConfirm: false,
   };
 
-  handleDelete = event => {
+  onClickDelete = event => {
     if (event) {
       event.preventDefault();
     }
 
     this.setState({
-      deleteButton: 'delete-button--hide',
+      showConfirm: true,
     });
-
-    setTimeout(() => {
-      this.setState({
-        deleteButton: 'delete-button--removed',
-      });
-    }, 100);
-
-    setTimeout(() => {
-      this.setState({
-        confirmSpan: 'confirm-delete--hide',
-      });
-    }, 100);
-
-    setTimeout(() => {
-      this.setState({
-        confirmSpan: 'confirm-delete--show',
-      });
-    }, 150);
   };
 
-  cancelDelete = event => {
-    event.preventDefault();
-
+  onClickCancel = event => {
+    if (event) {
+      event.preventDefault();
+    }
     this.setState({
-      confirmSpan: 'confirm-delete--hide',
+      showConfirm: false,
     });
-
-    setTimeout(() => {
-      this.setState({
-        confirmSpan: 'confirm-delete--removed',
-        deleteButton: 'delete-button--hide',
-      });
-    }, 140);
-
-    setTimeout(() => {
-      this.setState({
-        deleteButton: 'delete-button--show',
-      });
-    }, 190);
   };
 
   render() {
-    const { confirmDelete } = this.props;
+    const onClickConfirm = this.props.onConfirmDelete;
+    let showConfirm;
+    let showDeleteButton;
+
+    if (this.state.showConfirm) {
+      showConfirm = 'show';
+      showDeleteButton = 'hide';
+    } else {
+      showConfirm = 'hide';
+      showDeleteButton = 'show';
+    }
+
     return (
       <span className="delete-button-container">
-        <a className={this.state.deleteButton + ' btn btn-danger btn-small'} onClick={this.handleDelete}>
+        <a className={'delete-button ' + showDeleteButton + ' btn btn-danger btn-small'} onClick={this.onClickDelete}>
           <i className="fa fa-remove" />
         </a>
         <span className="confirm-delete-container">
-          <span className={this.state.confirmSpan}>
-            <a className="btn btn-small" onClick={this.cancelDelete}>
+          <span className={'confirm-delete ' + showConfirm}>
+            <a className="btn btn-small" onClick={this.onClickCancel}>
               Cancel
             </a>
-            <a className="btn btn-danger btn-small" onClick={confirmDelete}>
+            <a className="btn btn-danger btn-small" onClick={onClickConfirm}>
               Confirm Delete
             </a>
           </span>

+ 19 - 18
public/sass/components/_delete_button.scss

@@ -1,49 +1,50 @@
+// sets a fixed width so that the rest of the table
+// isn't affected by the animation
 .delete-button-container {
-  max-width: 24px;
   width: 24px;
   direction: rtl;
-  max-height: 38px;
-  display: block;
+  display: flex;
+  align-items: center;
 }
 
+//this container is used to make sure confirm-delete isn't
+//shown outside of table
 .confirm-delete-container {
   overflow: hidden;
   width: 145px;
-  display: block;
+  position: absolute;
+  z-index: 1;
 }
 
 .delete-button {
-  &--show {
-    display: inline-block;
+  position: absolute;
+
+  &.show {
     opacity: 1;
     transition: opacity 0.1s ease;
+    z-index: 2;
   }
 
-  &--hide {
-    display: inline-block;
+  &.hide {
     opacity: 0;
     transition: opacity 0.1s ease;
-  }
-  &--removed {
-    display: none;
+    z-index: 0;
   }
 }
 
 .confirm-delete {
-  &--show {
-    display: inline-block;
+  display: flex;
+  align-items: flex-start;
+
+  &.show {
     opacity: 1;
     transition: opacity 0.08s ease-out, transform 0.1s ease-out;
     transform: translateX(0);
   }
 
-  &--hide {
-    display: inline-block;
+  &.hide {
     opacity: 0;
     transition: opacity 0.12s ease-in, transform 0.14s ease-in;
     transform: translateX(100px);
   }
-  &--removed {
-    display: none;
-  }
 }