Commit f519f891 by Jack Westbrook Committed by GitHub

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
parent a9cdc4b1
...@@ -43,6 +43,7 @@ export const getSelectStyles = stylesFactory((theme: GrafanaTheme) => { ...@@ -43,6 +43,7 @@ export const getSelectStyles = stylesFactory((theme: GrafanaTheme) => {
font-size: ${theme.typography.size.sm}; font-size: ${theme.typography.size.sm};
color: ${theme.colors.textWeak}; color: ${theme.colors.textWeak};
white-space: normal; white-space: normal;
line-height: ${theme.typography.lineHeight.md};
`, `,
optionBody: css` optionBody: css`
label: grafana-select-option-body; label: grafana-select-option-body;
......
import React, { Component } from 'react'; import React, { Component } from 'react';
import { css } from 'emotion';
import config from 'app/core/config';
import { UserPicker } from 'app/core/components/Select/UserPicker'; import { UserPicker } from 'app/core/components/Select/UserPicker';
import { TeamPicker, Team } from 'app/core/components/Select/TeamPicker'; import { TeamPicker, Team } from 'app/core/components/Select/TeamPicker';
import { LegacyForms, Icon } from '@grafana/ui'; import { Button, Form, HorizontalGroup, Icon, Select, stylesFactory } from '@grafana/ui';
import { SelectableValue } from '@grafana/data'; import { GrafanaTheme, SelectableValue } from '@grafana/data';
import { User } from 'app/types'; import { User } from 'app/types';
import { import {
dashboardPermissionLevels, dashboardPermissionLevels,
...@@ -12,7 +14,6 @@ import { ...@@ -12,7 +14,6 @@ import {
NewDashboardAclItem, NewDashboardAclItem,
OrgRole, OrgRole,
} from 'app/types/acl'; } from 'app/types/acl';
const { Select } = LegacyForms;
export interface Props { export interface Props {
onAddPermission: (item: NewDashboardAclItem) => void; onAddPermission: (item: NewDashboardAclItem) => void;
...@@ -38,8 +39,8 @@ class AddPermissions extends Component<Props, NewDashboardAclItem> { ...@@ -38,8 +39,8 @@ class AddPermissions extends Component<Props, NewDashboardAclItem> {
}; };
} }
onTypeChanged = (evt: any) => { onTypeChanged = (item: any) => {
const type = evt.target.value as AclTarget; const type = item.value as AclTarget;
switch (type) { switch (type) {
case AclTarget.User: case AclTarget.User:
...@@ -67,8 +68,7 @@ class AddPermissions extends Component<Props, NewDashboardAclItem> { ...@@ -67,8 +68,7 @@ class AddPermissions extends Component<Props, NewDashboardAclItem> {
this.setState({ permission: permission.value! }); this.setState({ permission: permission.value! });
}; };
onSubmit = async (evt: React.SyntheticEvent) => { onSubmit = async () => {
evt.preventDefault();
await this.props.onAddPermission(this.state); await this.props.onAddPermission(this.state);
this.setState(this.getCleanState()); this.setState(this.getCleanState());
}; };
...@@ -88,59 +88,57 @@ class AddPermissions extends Component<Props, NewDashboardAclItem> { ...@@ -88,59 +88,57 @@ class AddPermissions extends Component<Props, NewDashboardAclItem> {
const newItem = this.state; const newItem = this.state;
const pickerClassName = 'min-width-20'; const pickerClassName = 'min-width-20';
const isValid = this.isValid(); const isValid = this.isValid();
const styles = getStyles(config.theme);
return ( return (
<div className="gf-form-inline cta-form"> <div className="cta-form">
<button className="cta-form__close btn btn-transparent" onClick={onCancel}> <button className="cta-form__close btn btn-transparent" onClick={onCancel}>
<Icon name="times" /> <Icon name="times" />
</button> </button>
<form name="addPermission" onSubmit={this.onSubmit}>
<h5>Add Permission For</h5> <h5>Add Permission For</h5>
<div className="gf-form-inline"> <Form maxWidth="none" onSubmit={this.onSubmit}>
<div className="gf-form"> {() => (
<div className="gf-form-select-wrapper"> <HorizontalGroup>
<select className="gf-form-input gf-size-auto" value={newItem.type} onChange={this.onTypeChanged}> <Select
{dashboardAclTargets.map((option, idx) => { isSearchable={false}
return ( value={this.state.type}
<option key={idx} value={option.value}> options={dashboardAclTargets}
{option.text} onChange={this.onTypeChanged}
</option> />
);
})}
</select>
</div>
</div>
{newItem.type === AclTarget.User ? ( {newItem.type === AclTarget.User ? (
<div className="gf-form">
<UserPicker onSelected={this.onUserSelected} className={pickerClassName} /> <UserPicker onSelected={this.onUserSelected} className={pickerClassName} />
</div>
) : null} ) : null}
{newItem.type === AclTarget.Team ? ( {newItem.type === AclTarget.Team ? (
<div className="gf-form">
<TeamPicker onSelected={this.onTeamSelected} className={pickerClassName} /> <TeamPicker onSelected={this.onTeamSelected} className={pickerClassName} />
</div>
) : null} ) : null}
<div className="gf-form"> <span className={styles.label}>Can</span>
<Select <Select
isSearchable={false} isSearchable={false}
value={this.state.permission}
options={dashboardPermissionLevels} options={dashboardPermissionLevels}
onChange={this.onPermissionChanged} onChange={this.onPermissionChanged}
className="gf-form-select-box__control--menu-right" width={25}
/> />
</div> <Button data-save-permission type="submit" disabled={!isValid}>
<div className="gf-form">
<button data-save-permission className="btn btn-primary" type="submit" disabled={!isValid}>
Save Save
</button> </Button>
</div> </HorizontalGroup>
</div> )}
</form> </Form>
</div> </div>
); );
} }
} }
const getStyles = stylesFactory((theme: GrafanaTheme) => ({
label: css`
color: ${theme.colors.textBlue};
font-weight: bold;
`,
}));
export default AddPermissions; export default AddPermissions;
import React, { Component } from 'react'; import React, { Component } from 'react';
import { LegacyForms, Icon } from '@grafana/ui'; import { Select, Icon } from '@grafana/ui';
import { dashboardPermissionLevels } from 'app/types/acl'; import { dashboardPermissionLevels } from 'app/types/acl';
const { Select } = LegacyForms;
export interface Props { export interface Props {
item: any; item: any;
...@@ -28,8 +27,7 @@ export default class DisabledPermissionListItem extends Component<Props, any> { ...@@ -28,8 +27,7 @@ export default class DisabledPermissionListItem extends Component<Props, any> {
<Select <Select
options={dashboardPermissionLevels} options={dashboardPermissionLevels}
onChange={() => {}} onChange={() => {}}
isDisabled={true} disabled={true}
className="gf-form-select-box__control--menu-right"
value={currentPermissionLevel} value={currentPermissionLevel}
/> />
</div> </div>
......
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import { LegacyForms, Icon } from '@grafana/ui'; import { Select, Icon } from '@grafana/ui';
import { SelectableValue } from '@grafana/data'; import { SelectableValue } from '@grafana/data';
import { dashboardPermissionLevels, DashboardAcl, PermissionLevel } from 'app/types/acl'; import { dashboardPermissionLevels, DashboardAcl, PermissionLevel } from 'app/types/acl';
import { FolderInfo } from 'app/types'; import { FolderInfo } from 'app/types';
const { Select } = LegacyForms;
const setClassNameHelper = (inherited: boolean) => { const setClassNameHelper = (inherited: boolean) => {
return inherited ? 'gf-form-disabled' : ''; return inherited ? 'gf-form-disabled' : '';
...@@ -75,16 +74,14 @@ export default class PermissionsListItem extends PureComponent<Props> { ...@@ -75,16 +74,14 @@ export default class PermissionsListItem extends PureComponent<Props> {
</td> </td>
<td className="query-keyword">Can</td> <td className="query-keyword">Can</td>
<td> <td>
<div className="gf-form">
<Select <Select
isSearchable={false} isSearchable={false}
options={dashboardPermissionLevels} options={dashboardPermissionLevels}
onChange={this.onPermissionChanged} onChange={this.onPermissionChanged}
isDisabled={item.inherited} disabled={item.inherited}
className="gf-form-select-box__control--menu-right"
value={currentPermissionLevel} value={currentPermissionLevel}
width={25}
/> />
</div>
</td> </td>
<td> <td>
{!item.inherited ? ( {!item.inherited ? (
......
import React from 'react'; import React from 'react';
export default () => { export default () => (
return ( <div>
<div className="">
<h5>What are Permissions?</h5> <h5>What are Permissions?</h5>
<p> <p>
An Access Control List (ACL) model is used to limit access to Dashboard Folders. A user or a Team can be An Access Control List (ACL) model is used to limit access to Dashboard Folders. A user or a Team can be assigned
assigned permissions for a folder or for a single dashboard. permissions for a folder or for a single dashboard.
</p> </p>
</div> </div>
); );
};
import React, { Component } from 'react'; import React, { Component } from 'react';
import _ from 'lodash'; import _ from 'lodash';
import { LegacyForms } from '@grafana/ui'; import { AsyncSelect } from '@grafana/ui';
import { debounce } from 'lodash'; import { debounce } from 'lodash';
import { getBackendSrv } from '@grafana/runtime'; import { getBackendSrv } from '@grafana/runtime';
const { AsyncSelect } = LegacyForms;
export interface Team { export interface Team {
id: number; id: number;
...@@ -72,7 +71,7 @@ export class TeamPicker extends Component<Props, State> { ...@@ -72,7 +71,7 @@ export class TeamPicker extends Component<Props, State> {
onChange={onSelected} onChange={onSelected}
className={className} className={className}
placeholder="Select a team" placeholder="Select a team"
noOptionsMessage={() => 'No teams found'} noOptionsMessage="No teams found"
/> />
</div> </div>
); );
......
...@@ -77,7 +77,7 @@ export enum AclTarget { ...@@ -77,7 +77,7 @@ export enum AclTarget {
export interface AclTargetInfo { export interface AclTargetInfo {
value: AclTarget; value: AclTarget;
text: string; label: string;
} }
export const dataSourceAclLevels = [ export const dataSourceAclLevels = [
...@@ -85,10 +85,10 @@ export const dataSourceAclLevels = [ ...@@ -85,10 +85,10 @@ export const dataSourceAclLevels = [
]; ];
export const dashboardAclTargets: AclTargetInfo[] = [ export const dashboardAclTargets: AclTargetInfo[] = [
{ value: AclTarget.Team, text: 'Team' }, { value: AclTarget.Team, label: 'Team' },
{ value: AclTarget.User, text: 'User' }, { value: AclTarget.User, label: 'User' },
{ value: AclTarget.Viewer, text: 'Everyone With Viewer Role' }, { value: AclTarget.Viewer, label: 'Everyone With Viewer Role' },
{ value: AclTarget.Editor, text: 'Everyone With Editor Role' }, { value: AclTarget.Editor, label: 'Everyone With Editor Role' },
]; ];
export const dashboardPermissionLevels: DashboardPermissionInfo[] = [ export const dashboardPermissionLevels: DashboardPermissionInfo[] = [
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment