瀏覽代碼

ux: POC - Update "Add permissions" design and add a fancy animation #10676

Johannes Schill 8 年之前
父節點
當前提交
2ad4c30bc6

+ 1 - 0
package.json

@@ -153,6 +153,7 @@
     "react-popper": "^0.7.5",
     "react-popper": "^0.7.5",
     "react-select": "^1.1.0",
     "react-select": "^1.1.0",
     "react-sizeme": "^2.3.6",
     "react-sizeme": "^2.3.6",
+    "react-transition-group": "^2.2.1",
     "remarkable": "^1.7.1",
     "remarkable": "^1.7.1",
     "rst2html": "github:thoward/rst2html#990cb89",
     "rst2html": "github:thoward/rst2html#990cb89",
     "rxjs": "^5.4.3",
     "rxjs": "^5.4.3",

+ 8 - 4
public/app/containers/ManageDashboards/FolderPermissions.tsx

@@ -7,7 +7,7 @@ import Permissions from 'app/core/components/Permissions/Permissions';
 import Tooltip from 'app/core/components/Tooltip/Tooltip';
 import Tooltip from 'app/core/components/Tooltip/Tooltip';
 import PermissionsInfo from 'app/core/components/Permissions/PermissionsInfo';
 import PermissionsInfo from 'app/core/components/Permissions/PermissionsInfo';
 import AddPermissions from 'app/core/components/Permissions/AddPermissions';
 import AddPermissions from 'app/core/components/Permissions/AddPermissions';
-
+import SlideDown from 'app/core/components/Animations/SlideDown';
 @inject('nav', 'folder', 'view', 'permissions')
 @inject('nav', 'folder', 'view', 'permissions')
 @observer
 @observer
 export class FolderPermissions extends Component<IContainerProps, any> {
 export class FolderPermissions extends Component<IContainerProps, any> {
@@ -48,14 +48,18 @@ export class FolderPermissions extends Component<IContainerProps, any> {
               <i className="gicon gicon-question gicon--has-hover" />
               <i className="gicon gicon-question gicon--has-hover" />
             </Tooltip>
             </Tooltip>
             <div className="page-action-bar__spacer" />
             <div className="page-action-bar__spacer" />
-            <button className="btn btn-success pull-right" onClick={this.handleAddPermission}>
+            <button
+              className="btn btn-success pull-right"
+              onClick={this.handleAddPermission}
+              disabled={permissions.isAddPermissionsVisible}
+            >
               <i className="fa fa-plus" />
               <i className="fa fa-plus" />
               Add Permission
               Add Permission
             </button>
             </button>
           </div>
           </div>
-          {permissions.isAddPermissionsVisible ? (
+          <SlideDown in={permissions.isAddPermissionsVisible}>
             <AddPermissions permissions={permissions} backendSrv={backendSrv} dashboardId={dashboardId} />
             <AddPermissions permissions={permissions} backendSrv={backendSrv} dashboardId={dashboardId} />
-          ) : null}
+          </SlideDown>
           <Permissions permissions={permissions} isFolder={true} dashboardId={dashboardId} backendSrv={backendSrv} />
           <Permissions permissions={permissions} isFolder={true} dashboardId={dashboardId} backendSrv={backendSrv} />
         </div>
         </div>
       </div>
       </div>

+ 37 - 0
public/app/core/components/Animations/SlideDown.tsx

@@ -0,0 +1,37 @@
+import React from 'react';
+import Transition from 'react-transition-group/Transition';
+
+const defaultMaxHeight = '200px'; // When animating using max-height we need to use a static value.
+// If this is not enough, pass in <SlideDown maxHeight="....
+const defaultDuration = 200;
+const defaultStyle = {
+  transition: `max-height ${defaultDuration}ms ease-in-out`,
+  overflow: 'hidden',
+};
+
+export default ({ children, in: inProp, maxHeight = defaultMaxHeight }) => {
+  // There are 4 main states a Transition can be in:
+  // ENTERING, ENTERED, EXITING, EXITED
+  // https://reactcommunity.org/react-transition-group/
+  const transitionStyles = {
+    exited: { maxHeight: 0 },
+    entering: { maxHeight: maxHeight },
+    entered: { maxHeight: maxHeight, overflow: 'visible' },
+    exiting: { maxHeight: 0 },
+  };
+
+  return (
+    <Transition in={inProp} timeout={defaultDuration}>
+      {state => (
+        <div
+          style={{
+            ...defaultStyle,
+            ...transitionStyles[state],
+          }}
+        >
+          {children}
+        </div>
+      )}
+    </Transition>
+  );
+};

+ 5 - 3
public/app/core/components/Permissions/AddPermissions.tsx

@@ -11,7 +11,6 @@ export interface IProps {
   backendSrv: any;
   backendSrv: any;
   dashboardId: any;
   dashboardId: any;
 }
 }
-
 @observer
 @observer
 class AddPermissions extends Component<IProps, any> {
 class AddPermissions extends Component<IProps, any> {
   constructor(props) {
   constructor(props) {
@@ -82,8 +81,11 @@ class AddPermissions extends Component<IProps, any> {
 
 
     return (
     return (
       <div className="gf-form-inline cta-form">
       <div className="gf-form-inline cta-form">
-        <form name="addPermission" className="gf-form-group" onSubmit={this.handleSubmit}>
-          <h6 className="muted">Add Permission For</h6>
+        <button className="cta-form__close btn btn-transparent" onClick={permissions.hideAddPermissions}>
+          <i className="fa fa-close" />
+        </button>
+        <form name="addPermission" onSubmit={this.handleSubmit}>
+          <h6>Add Permission For</h6>
           <div className="gf-form-inline">
           <div className="gf-form-inline">
             <div className="gf-form">
             <div className="gf-form">
               <div className="gf-form-select-wrapper">
               <div className="gf-form-select-wrapper">

+ 3 - 1
public/app/core/components/Picker/TeamPicker.tsx

@@ -67,11 +67,13 @@ class TeamPicker extends Component<IProps, any> {
           isLoading={isLoading}
           isLoading={isLoading}
           loadOptions={this.debouncedSearch}
           loadOptions={this.debouncedSearch}
           loadingPlaceholder="Loading..."
           loadingPlaceholder="Loading..."
+          noResultsText="No teams found"
           onChange={handlePicked}
           onChange={handlePicked}
-          className="width-8 gf-form-input gf-form-input--form-dropdown"
+          className="width-12 gf-form-input gf-form-input--form-dropdown"
           optionComponent={PickerOption}
           optionComponent={PickerOption}
           placeholder="Choose"
           placeholder="Choose"
           value={value}
           value={value}
+          autosize={true}
         />
         />
       </div>
       </div>
     );
     );

+ 1 - 1
public/app/core/components/Picker/UserPicker.tsx

@@ -68,7 +68,7 @@ class UserPicker extends Component<IProps, any> {
           loadingPlaceholder="Loading..."
           loadingPlaceholder="Loading..."
           noResultsText="No users found"
           noResultsText="No users found"
           onChange={handlePicked}
           onChange={handlePicked}
-          className="width-8 gf-form-input gf-form-input--form-dropdown"
+          className="width-12 gf-form-input gf-form-input--form-dropdown"
           optionComponent={PickerOption}
           optionComponent={PickerOption}
           placeholder="Choose"
           placeholder="Choose"
           value={value}
           value={value}

+ 4 - 0
public/sass/components/_buttons.scss

@@ -113,6 +113,10 @@
   //border: 1px solid $tight-form-func-highlight-bg;
   //border: 1px solid $tight-form-func-highlight-bg;
 }
 }
 
 
+.btn-transparent {
+  background-color: transparent;
+}
+
 .btn-outline-primary {
 .btn-outline-primary {
   @include button-outline-variant($btn-primary-bg);
   @include button-outline-variant($btn-primary-bg);
 }
 }

+ 13 - 1
public/sass/components/_gf-form.scss

@@ -274,6 +274,10 @@ $input-border: 1px solid $input-border-color;
     }
     }
   }
   }
 
 
+  .gf-form-input {
+    margin-right: 0;
+  }
+
   select.gf-form-input {
   select.gf-form-input {
     text-indent: 0.01px;
     text-indent: 0.01px;
     text-overflow: '';
     text-overflow: '';
@@ -394,7 +398,15 @@ select.gf-form-input ~ .gf-form-help-icon {
 }
 }
 
 
 .cta-form {
 .cta-form {
+  position: relative;
   padding: 1rem;
   padding: 1rem;
-  background-color: $dark-2;
+  background-color: $dark-4;
   margin-bottom: 1rem;
   margin-bottom: 1rem;
+  border-top: 3px solid $green;
+}
+
+.cta-form__close {
+  position: absolute;
+  right: 0;
+  top: 0;
 }
 }

+ 25 - 0
yarn.lock

@@ -1604,6 +1604,10 @@ center-align@^0.1.1:
     align-text "^0.1.3"
     align-text "^0.1.3"
     lazy-cache "^1.0.3"
     lazy-cache "^1.0.3"
 
 
+chain-function@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/chain-function/-/chain-function-1.0.0.tgz#0d4ab37e7e18ead0bdc47b920764118ce58733dc"
+
 chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3, chalk@~1.1.0, chalk@~1.1.1:
 chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3, chalk@~1.1.0, chalk@~1.1.1:
   version "1.1.3"
   version "1.1.3"
   resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
   resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
@@ -2801,6 +2805,10 @@ dom-converter@~0.1:
   dependencies:
   dependencies:
     utila "~0.3"
     utila "~0.3"
 
 
+dom-helpers@^3.2.0:
+  version "3.3.1"
+  resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.3.1.tgz#fc1a4e15ffdf60ddde03a480a9c0fece821dd4a6"
+
 dom-serialize@^2.2.0:
 dom-serialize@^2.2.0:
   version "2.2.1"
   version "2.2.1"
   resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b"
   resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b"
@@ -8318,6 +8326,17 @@ react-test-renderer@^16.0.0, react-test-renderer@^16.0.0-0:
     object-assign "^4.1.1"
     object-assign "^4.1.1"
     prop-types "^15.6.0"
     prop-types "^15.6.0"
 
 
+react-transition-group@^2.2.1:
+  version "2.2.1"
+  resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.2.1.tgz#e9fb677b79e6455fd391b03823afe84849df4a10"
+  dependencies:
+    chain-function "^1.0.0"
+    classnames "^2.2.5"
+    dom-helpers "^3.2.0"
+    loose-envify "^1.3.1"
+    prop-types "^15.5.8"
+    warning "^3.0.0"
+
 react@^16.2.0:
 react@^16.2.0:
   version "16.2.0"
   version "16.2.0"
   resolved "https://registry.yarnpkg.com/react/-/react-16.2.0.tgz#a31bd2dab89bff65d42134fa187f24d054c273ba"
   resolved "https://registry.yarnpkg.com/react/-/react-16.2.0.tgz#a31bd2dab89bff65d42134fa187f24d054c273ba"
@@ -10355,6 +10374,12 @@ walker@~1.0.5:
   dependencies:
   dependencies:
     makeerror "1.0.x"
     makeerror "1.0.x"
 
 
+warning@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c"
+  dependencies:
+    loose-envify "^1.0.0"
+
 watch@~0.18.0:
 watch@~0.18.0:
   version "0.18.0"
   version "0.18.0"
   resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986"
   resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986"