mirror of https://github.com/grafana/grafana.git
				
				
				
			Migration: Remove LegacyForms from dashboard folder permissions (#28564)
* refactor(permissionlist): replace legacyform components with next-gen equivalents * refactor(permissionlist): replace legacyform components * refactor(permissionlist): clean up PermissionsInfo * feat(grafana-ui): define line-height for Select option descriptions * refactor(permissionlist): remove debug code * refactor(permissionlist): simplify component tree with horizontalgroup. Add label * refactor(permissionlist): remove redundant classname from Select
This commit is contained in:
		
							parent
							
								
									a9cdc4b129
								
							
						
					
					
						commit
						f519f89103
					
				| 
						 | 
				
			
			@ -43,6 +43,7 @@ export const getSelectStyles = stylesFactory((theme: GrafanaTheme) => {
 | 
			
		|||
      font-size: ${theme.typography.size.sm};
 | 
			
		||||
      color: ${theme.colors.textWeak};
 | 
			
		||||
      white-space: normal;
 | 
			
		||||
      line-height: ${theme.typography.lineHeight.md};
 | 
			
		||||
    `,
 | 
			
		||||
    optionBody: css`
 | 
			
		||||
      label: grafana-select-option-body;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,10 @@
 | 
			
		|||
import React, { Component } from 'react';
 | 
			
		||||
import { css } from 'emotion';
 | 
			
		||||
import config from 'app/core/config';
 | 
			
		||||
import { UserPicker } from 'app/core/components/Select/UserPicker';
 | 
			
		||||
import { TeamPicker, Team } from 'app/core/components/Select/TeamPicker';
 | 
			
		||||
import { LegacyForms, Icon } from '@grafana/ui';
 | 
			
		||||
import { SelectableValue } from '@grafana/data';
 | 
			
		||||
import { Button, Form, HorizontalGroup, Icon, Select, stylesFactory } from '@grafana/ui';
 | 
			
		||||
import { GrafanaTheme, SelectableValue } from '@grafana/data';
 | 
			
		||||
import { User } from 'app/types';
 | 
			
		||||
import {
 | 
			
		||||
  dashboardPermissionLevels,
 | 
			
		||||
| 
						 | 
				
			
			@ -12,7 +14,6 @@ import {
 | 
			
		|||
  NewDashboardAclItem,
 | 
			
		||||
  OrgRole,
 | 
			
		||||
} from 'app/types/acl';
 | 
			
		||||
const { Select } = LegacyForms;
 | 
			
		||||
 | 
			
		||||
export interface Props {
 | 
			
		||||
  onAddPermission: (item: NewDashboardAclItem) => void;
 | 
			
		||||
| 
						 | 
				
			
			@ -38,8 +39,8 @@ class AddPermissions extends Component<Props, NewDashboardAclItem> {
 | 
			
		|||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  onTypeChanged = (evt: any) => {
 | 
			
		||||
    const type = evt.target.value as AclTarget;
 | 
			
		||||
  onTypeChanged = (item: any) => {
 | 
			
		||||
    const type = item.value as AclTarget;
 | 
			
		||||
 | 
			
		||||
    switch (type) {
 | 
			
		||||
      case AclTarget.User:
 | 
			
		||||
| 
						 | 
				
			
			@ -67,8 +68,7 @@ class AddPermissions extends Component<Props, NewDashboardAclItem> {
 | 
			
		|||
    this.setState({ permission: permission.value! });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  onSubmit = async (evt: React.SyntheticEvent) => {
 | 
			
		||||
    evt.preventDefault();
 | 
			
		||||
  onSubmit = async () => {
 | 
			
		||||
    await this.props.onAddPermission(this.state);
 | 
			
		||||
    this.setState(this.getCleanState());
 | 
			
		||||
  };
 | 
			
		||||
| 
						 | 
				
			
			@ -88,59 +88,57 @@ class AddPermissions extends Component<Props, NewDashboardAclItem> {
 | 
			
		|||
    const newItem = this.state;
 | 
			
		||||
    const pickerClassName = 'min-width-20';
 | 
			
		||||
    const isValid = this.isValid();
 | 
			
		||||
    const styles = getStyles(config.theme);
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
      <div className="gf-form-inline cta-form">
 | 
			
		||||
      <div className="cta-form">
 | 
			
		||||
        <button className="cta-form__close btn btn-transparent" onClick={onCancel}>
 | 
			
		||||
          <Icon name="times" />
 | 
			
		||||
        </button>
 | 
			
		||||
        <form name="addPermission" onSubmit={this.onSubmit}>
 | 
			
		||||
        <h5>Add Permission For</h5>
 | 
			
		||||
          <div className="gf-form-inline">
 | 
			
		||||
            <div className="gf-form">
 | 
			
		||||
              <div className="gf-form-select-wrapper">
 | 
			
		||||
                <select className="gf-form-input gf-size-auto" value={newItem.type} onChange={this.onTypeChanged}>
 | 
			
		||||
                  {dashboardAclTargets.map((option, idx) => {
 | 
			
		||||
                    return (
 | 
			
		||||
                      <option key={idx} value={option.value}>
 | 
			
		||||
                        {option.text}
 | 
			
		||||
                      </option>
 | 
			
		||||
                    );
 | 
			
		||||
                  })}
 | 
			
		||||
                </select>
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        <Form maxWidth="none" onSubmit={this.onSubmit}>
 | 
			
		||||
          {() => (
 | 
			
		||||
            <HorizontalGroup>
 | 
			
		||||
              <Select
 | 
			
		||||
                isSearchable={false}
 | 
			
		||||
                value={this.state.type}
 | 
			
		||||
                options={dashboardAclTargets}
 | 
			
		||||
                onChange={this.onTypeChanged}
 | 
			
		||||
              />
 | 
			
		||||
 | 
			
		||||
              {newItem.type === AclTarget.User ? (
 | 
			
		||||
              <div className="gf-form">
 | 
			
		||||
                <UserPicker onSelected={this.onUserSelected} className={pickerClassName} />
 | 
			
		||||
              </div>
 | 
			
		||||
              ) : null}
 | 
			
		||||
 | 
			
		||||
              {newItem.type === AclTarget.Team ? (
 | 
			
		||||
              <div className="gf-form">
 | 
			
		||||
                <TeamPicker onSelected={this.onTeamSelected} className={pickerClassName} />
 | 
			
		||||
              </div>
 | 
			
		||||
              ) : null}
 | 
			
		||||
 | 
			
		||||
            <div className="gf-form">
 | 
			
		||||
              <span className={styles.label}>Can</span>
 | 
			
		||||
 | 
			
		||||
              <Select
 | 
			
		||||
                isSearchable={false}
 | 
			
		||||
                value={this.state.permission}
 | 
			
		||||
                options={dashboardPermissionLevels}
 | 
			
		||||
                onChange={this.onPermissionChanged}
 | 
			
		||||
                className="gf-form-select-box__control--menu-right"
 | 
			
		||||
                width={25}
 | 
			
		||||
              />
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            <div className="gf-form">
 | 
			
		||||
              <button data-save-permission className="btn btn-primary" type="submit" disabled={!isValid}>
 | 
			
		||||
              <Button data-save-permission type="submit" disabled={!isValid}>
 | 
			
		||||
                Save
 | 
			
		||||
              </button>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </form>
 | 
			
		||||
              </Button>
 | 
			
		||||
            </HorizontalGroup>
 | 
			
		||||
          )}
 | 
			
		||||
        </Form>
 | 
			
		||||
      </div>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const getStyles = stylesFactory((theme: GrafanaTheme) => ({
 | 
			
		||||
  label: css`
 | 
			
		||||
    color: ${theme.colors.textBlue};
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
  `,
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
export default AddPermissions;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,6 @@
 | 
			
		|||
import React, { Component } from 'react';
 | 
			
		||||
import { LegacyForms, Icon } from '@grafana/ui';
 | 
			
		||||
import { Select, Icon } from '@grafana/ui';
 | 
			
		||||
import { dashboardPermissionLevels } from 'app/types/acl';
 | 
			
		||||
const { Select } = LegacyForms;
 | 
			
		||||
 | 
			
		||||
export interface Props {
 | 
			
		||||
  item: any;
 | 
			
		||||
| 
						 | 
				
			
			@ -28,8 +27,7 @@ export default class DisabledPermissionListItem extends Component<Props, any> {
 | 
			
		|||
            <Select
 | 
			
		||||
              options={dashboardPermissionLevels}
 | 
			
		||||
              onChange={() => {}}
 | 
			
		||||
              isDisabled={true}
 | 
			
		||||
              className="gf-form-select-box__control--menu-right"
 | 
			
		||||
              disabled={true}
 | 
			
		||||
              value={currentPermissionLevel}
 | 
			
		||||
            />
 | 
			
		||||
          </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,9 +1,8 @@
 | 
			
		|||
import React, { PureComponent } from 'react';
 | 
			
		||||
import { LegacyForms, Icon } from '@grafana/ui';
 | 
			
		||||
import { Select, Icon } from '@grafana/ui';
 | 
			
		||||
import { SelectableValue } from '@grafana/data';
 | 
			
		||||
import { dashboardPermissionLevels, DashboardAcl, PermissionLevel } from 'app/types/acl';
 | 
			
		||||
import { FolderInfo } from 'app/types';
 | 
			
		||||
const { Select } = LegacyForms;
 | 
			
		||||
 | 
			
		||||
const setClassNameHelper = (inherited: boolean) => {
 | 
			
		||||
  return inherited ? 'gf-form-disabled' : '';
 | 
			
		||||
| 
						 | 
				
			
			@ -75,16 +74,14 @@ export default class PermissionsListItem extends PureComponent<Props> {
 | 
			
		|||
        </td>
 | 
			
		||||
        <td className="query-keyword">Can</td>
 | 
			
		||||
        <td>
 | 
			
		||||
          <div className="gf-form">
 | 
			
		||||
          <Select
 | 
			
		||||
            isSearchable={false}
 | 
			
		||||
            options={dashboardPermissionLevels}
 | 
			
		||||
            onChange={this.onPermissionChanged}
 | 
			
		||||
              isDisabled={item.inherited}
 | 
			
		||||
              className="gf-form-select-box__control--menu-right"
 | 
			
		||||
            disabled={item.inherited}
 | 
			
		||||
            value={currentPermissionLevel}
 | 
			
		||||
            width={25}
 | 
			
		||||
          />
 | 
			
		||||
          </div>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td>
 | 
			
		||||
          {!item.inherited ? (
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,13 +1,11 @@
 | 
			
		|||
import React from 'react';
 | 
			
		||||
 | 
			
		||||
export default () => {
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="">
 | 
			
		||||
export default () => (
 | 
			
		||||
  <div>
 | 
			
		||||
    <h5>What are Permissions?</h5>
 | 
			
		||||
    <p>
 | 
			
		||||
        An Access Control List (ACL) model is used to limit access to Dashboard Folders. A user or a Team can be
 | 
			
		||||
        assigned permissions for a folder or for a single dashboard.
 | 
			
		||||
      An Access Control List (ACL) model is used to limit access to Dashboard Folders. A user or a Team can be assigned
 | 
			
		||||
      permissions for a folder or for a single dashboard.
 | 
			
		||||
    </p>
 | 
			
		||||
  </div>
 | 
			
		||||
);
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,9 +1,8 @@
 | 
			
		|||
import React, { Component } from 'react';
 | 
			
		||||
import _ from 'lodash';
 | 
			
		||||
import { LegacyForms } from '@grafana/ui';
 | 
			
		||||
import { AsyncSelect } from '@grafana/ui';
 | 
			
		||||
import { debounce } from 'lodash';
 | 
			
		||||
import { getBackendSrv } from '@grafana/runtime';
 | 
			
		||||
const { AsyncSelect } = LegacyForms;
 | 
			
		||||
 | 
			
		||||
export interface Team {
 | 
			
		||||
  id: number;
 | 
			
		||||
| 
						 | 
				
			
			@ -72,7 +71,7 @@ export class TeamPicker extends Component<Props, State> {
 | 
			
		|||
          onChange={onSelected}
 | 
			
		||||
          className={className}
 | 
			
		||||
          placeholder="Select a team"
 | 
			
		||||
          noOptionsMessage={() => 'No teams found'}
 | 
			
		||||
          noOptionsMessage="No teams found"
 | 
			
		||||
        />
 | 
			
		||||
      </div>
 | 
			
		||||
    );
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -77,7 +77,7 @@ export enum AclTarget {
 | 
			
		|||
 | 
			
		||||
export interface AclTargetInfo {
 | 
			
		||||
  value: AclTarget;
 | 
			
		||||
  text: string;
 | 
			
		||||
  label: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const dataSourceAclLevels = [
 | 
			
		||||
| 
						 | 
				
			
			@ -85,10 +85,10 @@ export const dataSourceAclLevels = [
 | 
			
		|||
];
 | 
			
		||||
 | 
			
		||||
export const dashboardAclTargets: AclTargetInfo[] = [
 | 
			
		||||
  { value: AclTarget.Team, text: 'Team' },
 | 
			
		||||
  { value: AclTarget.User, text: 'User' },
 | 
			
		||||
  { value: AclTarget.Viewer, text: 'Everyone With Viewer Role' },
 | 
			
		||||
  { value: AclTarget.Editor, text: 'Everyone With Editor Role' },
 | 
			
		||||
  { value: AclTarget.Team, label: 'Team' },
 | 
			
		||||
  { value: AclTarget.User, label: 'User' },
 | 
			
		||||
  { value: AclTarget.Viewer, label: 'Everyone With Viewer Role' },
 | 
			
		||||
  { value: AclTarget.Editor, label: 'Everyone With Editor Role' },
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
export const dashboardPermissionLevels: DashboardPermissionInfo[] = [
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue