Commit 3a94918b by Johannes Schill Committed by Daniel Lee

dashfolders: Rename UserPicker folder => Picker. Inject the permission-store in…

dashfolders: Rename UserPicker folder => Picker. Inject the permission-store in the FolderPermissions-container instead of the Permissions component, add the PermissionsStore to the RootStore and and the error-message to the Permissions-store #10275
parent 126607de
import { SearchStore } from './../stores/SearchStore/SearchStore'; import { SearchStore } from './../stores/SearchStore/SearchStore';
import { ServerStatsStore } from './../stores/ServerStatsStore/ServerStatsStore'; import { ServerStatsStore } from './../stores/ServerStatsStore/ServerStatsStore';
import { NavStore } from './../stores/NavStore/NavStore'; import { NavStore } from './../stores/NavStore/NavStore';
import { PermissionsStore } from './../stores/PermissionsStore/PermissionsStore';
import { AlertListStore } from './../stores/AlertListStore/AlertListStore'; import { AlertListStore } from './../stores/AlertListStore/AlertListStore';
import { ViewStore } from './../stores/ViewStore/ViewStore'; import { ViewStore } from './../stores/ViewStore/ViewStore';
import { FolderStore } from './../stores/FolderStore/FolderStore'; import { FolderStore } from './../stores/FolderStore/FolderStore';
...@@ -10,6 +11,7 @@ interface IContainerProps { ...@@ -10,6 +11,7 @@ interface IContainerProps {
serverStats: typeof ServerStatsStore.Type; serverStats: typeof ServerStatsStore.Type;
nav: typeof NavStore.Type; nav: typeof NavStore.Type;
alertList: typeof AlertListStore.Type; alertList: typeof AlertListStore.Type;
permissions: typeof PermissionsStore.Type;
view: typeof ViewStore.Type; view: typeof ViewStore.Type;
folder: typeof FolderStore.Type; folder: typeof FolderStore.Type;
backendSrv: any; backendSrv: any;
......
...@@ -5,7 +5,7 @@ import IContainerProps from 'app/containers/IContainerProps'; ...@@ -5,7 +5,7 @@ import IContainerProps from 'app/containers/IContainerProps';
import PageHeader from 'app/core/components/PageHeader/PageHeader'; import PageHeader from 'app/core/components/PageHeader/PageHeader';
import Permissions from 'app/core/components/Permissions/Permissions'; import Permissions from 'app/core/components/Permissions/Permissions';
@inject('nav', 'folder', 'view') @inject('nav', 'folder', 'view', 'permissions')
@observer @observer
export class FolderPermissions extends Component<IContainerProps, any> { export class FolderPermissions extends Component<IContainerProps, any> {
dashboard: any; dashboard: any;
...@@ -24,7 +24,7 @@ export class FolderPermissions extends Component<IContainerProps, any> { ...@@ -24,7 +24,7 @@ export class FolderPermissions extends Component<IContainerProps, any> {
} }
render() { render() {
const { nav, folder } = this.props; const { nav, folder, permissions } = this.props;
if (!folder.folder || !nav.main) { if (!folder.folder || !nav.main) {
return <h2>Loading</h2>; return <h2>Loading</h2>;
...@@ -34,7 +34,13 @@ export class FolderPermissions extends Component<IContainerProps, any> { ...@@ -34,7 +34,13 @@ export class FolderPermissions extends Component<IContainerProps, any> {
<div> <div>
<PageHeader model={nav as any} /> <PageHeader model={nav as any} />
<div className="page-container page-body"> <div className="page-container page-body">
<Permissions isFolder={true} error="" newType="" dashboardId={1} backendSrv={this.props.backendSrv} /> <Permissions
permissions={permissions}
isFolder={true}
error=""
dashboardId={1}
backendSrv={this.props.backendSrv}
/>
</div> </div>
</div> </div>
); );
......
...@@ -4,8 +4,8 @@ import PageHeader from './components/PageHeader/PageHeader'; ...@@ -4,8 +4,8 @@ import PageHeader from './components/PageHeader/PageHeader';
import EmptyListCTA from './components/EmptyListCTA/EmptyListCTA'; import EmptyListCTA from './components/EmptyListCTA/EmptyListCTA';
import LoginBackground from './components/Login/LoginBackground'; import LoginBackground from './components/Login/LoginBackground';
import { SearchResult } from './components/search/SearchResult'; import { SearchResult } from './components/search/SearchResult';
import UserPicker from './components/UserPicker/UserPicker';
import { TagFilter } from './components/TagFilter/TagFilter'; import { TagFilter } from './components/TagFilter/TagFilter';
import UserPicker from './components/Picker/UserPicker';
import Permissions from './components/Permissions/Permissions'; import Permissions from './components/Permissions/Permissions';
export function registerAngularDirectives() { export function registerAngularDirectives() {
...@@ -20,12 +20,5 @@ export function registerAngularDirectives() { ...@@ -20,12 +20,5 @@ export function registerAngularDirectives() {
['tagOptions', { watchDepth: 'reference' }], ['tagOptions', { watchDepth: 'reference' }],
]); ]);
react2AngularDirective('selectUserPicker', UserPicker, ['backendSrv', 'handlePicked']); react2AngularDirective('selectUserPicker', UserPicker, ['backendSrv', 'handlePicked']);
react2AngularDirective('permissions', Permissions, [ react2AngularDirective('permissions', Permissions, ['error', 'aclTypes', 'typeChanged', 'backendSrv', 'dashboardId']);
'error',
'newType',
'aclTypes',
'typeChanged',
'backendSrv',
'dashboardId',
]);
} }
import React, { Component } from 'react'; import React, { Component } from 'react';
import PermissionsList from './PermissionsList'; import PermissionsList from './PermissionsList';
import { inject, observer } from 'mobx-react'; import { observer } from 'mobx-react';
import UserPicker, { User } from 'app/core/components/UserPicker/UserPicker'; import UserPicker, { User } from 'app/core/components/Picker/UserPicker';
import TeamPicker, { Team } from 'app/core/components/UserPicker/TeamPicker'; import TeamPicker, { Team } from 'app/core/components/Picker/TeamPicker';
export interface DashboardAcl { export interface DashboardAcl {
id?: number; id?: number;
...@@ -24,17 +24,14 @@ export interface DashboardAcl { ...@@ -24,17 +24,14 @@ export interface DashboardAcl {
export interface IProps { export interface IProps {
error: string; error: string;
newType: string;
dashboardId: number; dashboardId: number;
permissions?: any; permissions?: any;
isFolder: boolean; isFolder: boolean;
backendSrv: any; backendSrv: any;
} }
@inject('permissions')
@observer @observer
class Permissions extends Component<IProps, any> { class Permissions extends Component<IProps, any> {
// TODO Remove Inner from Name when we get access via ReactContainer
dashboardId: any; dashboardId: any;
meta: any; meta: any;
items: DashboardAcl[]; items: DashboardAcl[];
...@@ -51,8 +48,6 @@ class Permissions extends Component<IProps, any> { ...@@ -51,8 +48,6 @@ class Permissions extends Component<IProps, any> {
error: string; error: string;
refreshList: any; refreshList: any;
readonly duplicateError = 'This permission exists already.';
constructor(props) { constructor(props) {
super(props); super(props);
const { dashboardId, permissions, isFolder } = this.props; const { dashboardId, permissions, isFolder } = this.props;
...@@ -69,10 +64,6 @@ class Permissions extends Component<IProps, any> { ...@@ -69,10 +64,6 @@ class Permissions extends Component<IProps, any> {
}; };
} }
componentWillReceiveProps(nextProps) {
console.log('nextProps', nextProps);
}
permissionChanged(index: number, permission: number, permissionName: string) { permissionChanged(index: number, permission: number, permissionName: string) {
const { permissions } = this.props; const { permissions } = this.props;
permissions.updatePermissionOnIndex(index, permission, permissionName); permissions.updatePermissionOnIndex(index, permission, permissionName);
...@@ -127,7 +118,7 @@ class Permissions extends Component<IProps, any> { ...@@ -127,7 +118,7 @@ class Permissions extends Component<IProps, any> {
render() { render() {
console.log('Permissions render'); console.log('Permissions render');
const { error, permissions, backendSrv } = this.props; const { permissions, backendSrv } = this.props;
const { newType } = this.state; const { newType } = this.state;
return ( return (
...@@ -154,25 +145,11 @@ class Permissions extends Component<IProps, any> { ...@@ -154,25 +145,11 @@ class Permissions extends Component<IProps, any> {
); );
})} })}
</select> </select>
{/* <select
className="gf-form-input gf-size-auto"
ng-model="ctrl.newType"
ng-options="p.value as p.text for p in ctrl.aclTypes"
ng-change="ctrl.typeChanged()"
/> */}
</div> </div>
</div> </div>
{newType === 'User' ? ( {newType === 'User' ? (
<div className="gf-form"> <div className="gf-form">
{/* <user-picker user-picked="ctrl.userPicked($user)" />
<select-user-picker
backendSrv="ctrl.backendSrv"
teamId="ctrl.$routeParams.id"
refreshList="ctrl.get"
teamMembers="ctrl.teamMembers"
/> */}
<UserPicker backendSrv={backendSrv} handlePicked={this.userPicked} /> <UserPicker backendSrv={backendSrv} handlePicked={this.userPicked} />
</div> </div>
) : null} ) : null}
...@@ -184,11 +161,11 @@ class Permissions extends Component<IProps, any> { ...@@ -184,11 +161,11 @@ class Permissions extends Component<IProps, any> {
) : null} ) : null}
</div> </div>
</form> </form>
{error ? ( {permissions.error ? (
<div className="gf-form width-17"> <div className="gf-form width-17">
<span ng-if="ctrl.error" className="text-error p-l-1"> <span ng-if="ctrl.error" className="text-error p-l-1">
<i className="fa fa-warning" /> <i className="fa fa-warning" />
{error} {permissions.error}
</span> </span>
</div> </div>
) : null} ) : null}
......
import React from 'react'; import React from 'react';
import renderer from 'react-test-renderer'; import renderer from 'react-test-renderer';
import UserPickerOption from './UserPickerOption'; import PickerOption from './PickerOption';
const model = { const model = {
onSelect: () => {}, onSelect: () => {},
...@@ -14,9 +14,9 @@ const model = { ...@@ -14,9 +14,9 @@ const model = {
className: 'class-for-user-picker', className: 'class-for-user-picker',
}; };
describe('UserPickerOption', () => { describe('PickerOption', () => {
it('renders correctly', () => { it('renders correctly', () => {
const tree = renderer.create(<UserPickerOption {...model} />).toJSON(); const tree = renderer.create(<PickerOption {...model} />).toJSON();
expect(tree).toMatchSnapshot(); expect(tree).toMatchSnapshot();
}); });
}); });
import React, { Component } from 'react'; import React, { Component } from 'react';
import Select from 'react-select'; import Select from 'react-select';
import UserPickerOption from './UserPickerOption'; import PickerOption from './PickerOption';
import withPicker from './withPicker'; import withPicker from './withPicker';
import { debounce } from 'lodash'; import { debounce } from 'lodash';
...@@ -26,7 +26,7 @@ class TeamPicker extends Component<IProps, any> { ...@@ -26,7 +26,7 @@ class TeamPicker extends Component<IProps, any> {
super(props); super(props);
this.state = {}; this.state = {};
this.search = this.search.bind(this); this.search = this.search.bind(this);
// this.handleChange = this.handleChange.bind(this);
this.debouncedSearch = debounce(this.search, 300, { this.debouncedSearch = debounce(this.search, 300, {
leading: true, leading: true,
trailing: false, trailing: false,
...@@ -37,10 +37,8 @@ class TeamPicker extends Component<IProps, any> { ...@@ -37,10 +37,8 @@ class TeamPicker extends Component<IProps, any> {
const { toggleLoading, backendSrv } = this.props; const { toggleLoading, backendSrv } = this.props;
toggleLoading(true); toggleLoading(true);
return backendSrv.get(`/api/teams/search?perpage=10&page=1&query=${query}`).then(result => { return backendSrv.get(`/api/teams/search?perpage=10&page=1&query=${query}`).then(result => {
const teams = result.teams.map(team => { const teams = result.teams.map(team => {
// return { text: ug.name, value: ug };
return { return {
id: team.id, id: team.id,
label: team.name, label: team.name,
...@@ -62,7 +60,7 @@ class TeamPicker extends Component<IProps, any> { ...@@ -62,7 +60,7 @@ class TeamPicker extends Component<IProps, any> {
<div className="user-picker"> <div className="user-picker">
<AsyncComponent <AsyncComponent
valueKey="id" valueKey="id"
multi={this.state.multi} multi={false}
labelKey="label" labelKey="label"
cache={false} cache={false}
isLoading={isLoading} isLoading={isLoading}
...@@ -70,7 +68,7 @@ class TeamPicker extends Component<IProps, any> { ...@@ -70,7 +68,7 @@ class TeamPicker extends Component<IProps, any> {
loadingPlaceholder="Loading..." loadingPlaceholder="Loading..."
onChange={handlePicked} onChange={handlePicked}
className="width-8 gf-form-input gf-form-input--form-dropdown" className="width-8 gf-form-input gf-form-input--form-dropdown"
optionComponent={UserPickerOption} optionComponent={PickerOption}
placeholder="Choose" placeholder="Choose"
/> />
</div> </div>
......
import React, { Component } from 'react'; import React, { Component } from 'react';
import Select from 'react-select'; import Select from 'react-select';
import UserPickerOption from './UserPickerOption'; import PickerOption from './PickerOption';
import withPicker from './withPicker'; import withPicker from './withPicker';
import { debounce } from 'lodash'; import { debounce } from 'lodash';
...@@ -26,7 +26,7 @@ class UserPicker extends Component<IProps, any> { ...@@ -26,7 +26,7 @@ class UserPicker extends Component<IProps, any> {
super(props); super(props);
this.state = {}; this.state = {};
this.search = this.search.bind(this); this.search = this.search.bind(this);
// this.handleChange = this.handleChange.bind(this);
this.debouncedSearch = debounce(this.search, 300, { this.debouncedSearch = debounce(this.search, 300, {
leading: true, leading: true,
trailing: false, trailing: false,
...@@ -59,7 +59,7 @@ class UserPicker extends Component<IProps, any> { ...@@ -59,7 +59,7 @@ class UserPicker extends Component<IProps, any> {
<div className="user-picker"> <div className="user-picker">
<AsyncComponent <AsyncComponent
valueKey="id" valueKey="id"
multi={this.state.multi} multi={false}
labelKey="label" labelKey="label"
cache={false} cache={false}
isLoading={isLoading} isLoading={isLoading}
...@@ -68,7 +68,7 @@ class UserPicker extends Component<IProps, any> { ...@@ -68,7 +68,7 @@ class UserPicker extends Component<IProps, any> {
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-8 gf-form-input gf-form-input--form-dropdown"
optionComponent={UserPickerOption} optionComponent={PickerOption}
placeholder="Choose" placeholder="Choose"
/> />
</div> </div>
......
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`UserPickerOption renders correctly 1`] = ` exports[`PickerOption renders correctly 1`] = `
<button <button
className="user-picker-option__button btn btn-link class-for-user-picker" className="user-picker-option__button btn btn-link class-for-user-picker"
onMouseDown={[Function]} onMouseDown={[Function]}
......
...@@ -5,13 +5,6 @@ export interface IProps { ...@@ -5,13 +5,6 @@ export interface IProps {
handlePicked: (data) => void; handlePicked: (data) => void;
} }
// export interface User {
// id: number;
// name: string;
// login: string;
// email: string;
// }
export default function withPicker(WrappedComponent) { export default function withPicker(WrappedComponent) {
return class WithPicker extends Component<IProps, any> { return class WithPicker extends Component<IProps, any> {
constructor(props) { constructor(props) {
...@@ -19,7 +12,6 @@ export default function withPicker(WrappedComponent) { ...@@ -19,7 +12,6 @@ export default function withPicker(WrappedComponent) {
this.toggleLoading = this.toggleLoading.bind(this); this.toggleLoading = this.toggleLoading.bind(this);
this.state = { this.state = {
multi: false,
isLoading: false, isLoading: false,
}; };
} }
......
...@@ -10,6 +10,7 @@ export const PermissionsStore = types ...@@ -10,6 +10,7 @@ export const PermissionsStore = types
dashboardId: types.maybe(types.number), dashboardId: types.maybe(types.number),
canUpdate: types.boolean, canUpdate: types.boolean,
items: types.optional(types.array(PermissionsStoreItem), []), items: types.optional(types.array(PermissionsStoreItem), []),
error: types.maybe(types.string),
originalItems: types.optional(types.array(PermissionsStoreItem), []), originalItems: types.optional(types.array(PermissionsStoreItem), []),
}) })
.views(self => ({ .views(self => ({
...@@ -19,7 +20,7 @@ export const PermissionsStore = types ...@@ -19,7 +20,7 @@ export const PermissionsStore = types
}); });
if (dupe) { if (dupe) {
this.error = duplicateError; self.error = duplicateError;
return false; return false;
} }
...@@ -39,6 +40,7 @@ export const PermissionsStore = types ...@@ -39,6 +40,7 @@ export const PermissionsStore = types
self.fetching = false; self.fetching = false;
}), }),
addStoreItem: item => { addStoreItem: item => {
self.error = null;
if (!self.isValid(item)) { if (!self.isValid(item)) {
return; return;
} }
...@@ -47,14 +49,17 @@ export const PermissionsStore = types ...@@ -47,14 +49,17 @@ export const PermissionsStore = types
self.canUpdate = true; self.canUpdate = true;
}, },
removeStoreItem: idx => { removeStoreItem: idx => {
self.error = null;
self.items.splice(idx, 1); self.items.splice(idx, 1);
self.canUpdate = true; self.canUpdate = true;
}, },
updatePermissionOnIndex(idx: number, permission: number, permissionName: string) { updatePermissionOnIndex(idx: number, permission: number, permissionName: string) {
self.error = null;
self.items[idx].updatePermission(permission, permissionName); self.items[idx].updatePermission(permission, permissionName);
self.canUpdate = true; self.canUpdate = true;
}, },
update: flow(function* update(dashboardId: number) { update: flow(function* update(dashboardId: number) {
self.error = null;
const backendSrv = getEnv(self).backendSrv; const backendSrv = getEnv(self).backendSrv;
const updated = []; const updated = [];
for (let item of self.items) { for (let item of self.items) {
......
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