studiokit-scaffolding-js 4.3.20 → 4.5.0-next.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/HOC/SearchPersistorComponent.d.ts +34 -53
- package/lib/components/HOC/SearchPersistorComponent.js +0 -20
- package/lib/components/UserRoles/Add.d.ts +7 -7
- package/lib/components/UserRoles/Add.js +5 -5
- package/lib/components/UserRoles/Context.d.ts +32 -0
- package/lib/components/UserRoles/Context.js +13 -0
- package/lib/components/UserRoles/RoleCell.d.ts +3 -17
- package/lib/components/UserRoles/RoleCell.js +77 -24
- package/lib/components/UserRoles/Select.d.ts +18 -19
- package/lib/components/UserRoles/Select.js +33 -19
- package/lib/components/UserRoles/Table.d.ts +0 -9
- package/lib/components/UserRoles/Table.js +22 -12
- package/lib/components/UserRoles/index.d.ts +55 -27
- package/lib/components/UserRoles/index.js +187 -84
- package/lib/constants/mockData.d.ts +9 -11
- package/lib/constants/mockData.js +39 -79
- package/lib/endpointMappings.d.ts +1 -1
- package/lib/endpointMappings.js +11 -21
- package/lib/types/Group.d.ts +2 -2
- package/lib/types/RoleDescription.d.ts +1 -1
- package/lib/types/UserRole.d.ts +2 -7
- package/lib/utils/entityUserRole.js +1 -3
- package/lib/utils/groupRoles.d.ts +3 -3
- package/lib/utils/groupRoles.js +3 -2
- package/lib/utils/userRole.d.ts +6 -0
- package/lib/utils/userRole.js +21 -1
- package/package.json +3 -3
|
@@ -1,17 +1,13 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ComponentClass, ComponentType } from 'react';
|
|
2
2
|
import { Dispatch } from 'redux';
|
|
3
3
|
import { BaseReduxState, Search } from '../../types';
|
|
4
|
-
export interface SearchPersistorProps {
|
|
5
|
-
persistSearch: (search?:
|
|
6
|
-
persistedSearch:
|
|
4
|
+
export interface SearchPersistorProps<T extends Search = Search> {
|
|
5
|
+
persistSearch: (search?: T) => void;
|
|
6
|
+
persistedSearch: T;
|
|
7
7
|
}
|
|
8
|
-
interface
|
|
9
|
-
search:
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
export interface SearchPersistorMethods {
|
|
13
|
-
setSearchDefaults: (doSearch: () => void, search: Search) => void;
|
|
14
|
-
updateAndPersistSearch: (search?: Search, callback?: () => void) => void;
|
|
8
|
+
export interface SearchPersistorMethods<T extends Search = Search> {
|
|
9
|
+
setSearchDefaults: (doSearch: () => void, search: T) => void;
|
|
10
|
+
updateAndPersistSearch: (search?: Search | T, callback?: () => void) => void;
|
|
15
11
|
handleSearchClick: () => void;
|
|
16
12
|
handleChangeTab: (selectedTab: number) => void;
|
|
17
13
|
handleKeywordsChange: (event: any) => void;
|
|
@@ -19,48 +15,13 @@ export interface SearchPersistorMethods {
|
|
|
19
15
|
handleQueryAllChange: (event: any) => void;
|
|
20
16
|
resetSearch: () => void;
|
|
21
17
|
}
|
|
22
|
-
export interface SearchPersistorWrappedProps extends SearchPersistorProps
|
|
23
|
-
search?:
|
|
18
|
+
export interface SearchPersistorWrappedProps<T extends Search = Search> extends SearchPersistorProps<T>, SearchPersistorMethods<T> {
|
|
19
|
+
search?: T;
|
|
24
20
|
}
|
|
25
|
-
export declare function configureSearchPersistorComponent<TOwnProps extends {}>(WrappedComponent: ComponentType<TOwnProps & SearchPersistorWrappedProps>):
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
setSearchDefaults: (doSearch: () => void, search: Search) => void;
|
|
30
|
-
updateAndPersistSearch: (search?: Search | undefined, callback?: (() => void) | undefined) => void;
|
|
31
|
-
handleSearchClick: () => void;
|
|
32
|
-
handleChangeTab: (selectedTab: number) => void;
|
|
33
|
-
handleKeywordsChange: (event: any) => void;
|
|
34
|
-
handleKeywordsKeyDown: (event: any) => void;
|
|
35
|
-
handleQueryAllChange: (event: any) => void;
|
|
36
|
-
resetSearch: () => void;
|
|
37
|
-
render(): JSX.Element;
|
|
38
|
-
context: any;
|
|
39
|
-
setState<K extends "search" | "defaultSearch">(state: SearchPersistorState | ((prevState: Readonly<SearchPersistorState>, props: Readonly<TOwnProps & SearchPersistorProps>) => SearchPersistorState | Pick<SearchPersistorState, K> | null) | Pick<SearchPersistorState, K> | null, callback?: (() => void) | undefined): void;
|
|
40
|
-
forceUpdate(callback?: (() => void) | undefined): void;
|
|
41
|
-
readonly props: Readonly<TOwnProps & SearchPersistorProps> & Readonly<{
|
|
42
|
-
children?: React.ReactNode;
|
|
43
|
-
}>;
|
|
44
|
-
state: Readonly<SearchPersistorState>;
|
|
45
|
-
refs: {
|
|
46
|
-
[key: string]: React.ReactInstance;
|
|
47
|
-
};
|
|
48
|
-
shouldComponentUpdate?(nextProps: Readonly<TOwnProps & SearchPersistorProps>, nextState: Readonly<SearchPersistorState>, nextContext: any): boolean;
|
|
49
|
-
componentWillUnmount?(): void;
|
|
50
|
-
componentDidCatch?(error: Error, errorInfo: React.ErrorInfo): void;
|
|
51
|
-
getSnapshotBeforeUpdate?(prevProps: Readonly<TOwnProps & SearchPersistorProps>, prevState: Readonly<SearchPersistorState>): any;
|
|
52
|
-
componentDidUpdate?(prevProps: Readonly<TOwnProps & SearchPersistorProps>, prevState: Readonly<SearchPersistorState>, snapshot?: any): void;
|
|
53
|
-
componentWillMount?(): void;
|
|
54
|
-
UNSAFE_componentWillMount?(): void;
|
|
55
|
-
componentWillReceiveProps?(nextProps: Readonly<TOwnProps & SearchPersistorProps>, nextContext: any): void;
|
|
56
|
-
UNSAFE_componentWillReceiveProps?(nextProps: Readonly<TOwnProps & SearchPersistorProps>, nextContext: any): void;
|
|
57
|
-
componentWillUpdate?(nextProps: Readonly<TOwnProps & SearchPersistorProps>, nextState: Readonly<SearchPersistorState>, nextContext: any): void;
|
|
58
|
-
UNSAFE_componentWillUpdate?(nextProps: Readonly<TOwnProps & SearchPersistorProps>, nextState: Readonly<SearchPersistorState>, nextContext: any): void;
|
|
59
|
-
};
|
|
60
|
-
contextType?: React.Context<any> | undefined;
|
|
61
|
-
};
|
|
62
|
-
export declare const configureMapStateToProps: (key: string) => (state: BaseReduxState) => SearchPersistorProps;
|
|
63
|
-
export declare const configureMapDispatchToProps: (key: string) => (dispatch: Dispatch) => SearchPersistorProps;
|
|
21
|
+
export declare function configureSearchPersistorComponent<TOwnProps extends {}>(WrappedComponent: ComponentType<TOwnProps & SearchPersistorWrappedProps>): ComponentType<TOwnProps & SearchPersistorProps>;
|
|
22
|
+
export declare function configureSearchPersistorComponent<TOwnProps extends {}, TSearchType extends Search>(WrappedComponent: ComponentType<TOwnProps & SearchPersistorWrappedProps<TSearchType>>): ComponentType<TOwnProps & SearchPersistorProps<TSearchType>>;
|
|
23
|
+
export declare const configureMapStateToProps: <TSearchType extends Search>(key: string) => (state: BaseReduxState) => SearchPersistorProps<TSearchType>;
|
|
24
|
+
export declare const configureMapDispatchToProps: <TSearchType extends Search>(key: string) => (dispatch: Dispatch) => SearchPersistorProps<TSearchType>;
|
|
64
25
|
/**
|
|
65
26
|
* HOC to handle persistence and restoration of "Manage" components search parameters.
|
|
66
27
|
* Note: if you store a search date in a child component, make sure it’s called `date`.
|
|
@@ -82,4 +43,24 @@ export declare const configureMapDispatchToProps: (key: string) => (dispatch: Di
|
|
|
82
43
|
* @returns The wrapped component, passing down `search` and `persistSearch` as props
|
|
83
44
|
*/
|
|
84
45
|
export default function searchPersistorComponent<TOwnProps extends SearchPersistorWrappedProps>(WrappedComponent: ComponentType<TOwnProps>, key: string): ComponentClass<Omit<TOwnProps, keyof SearchPersistorWrappedProps>>;
|
|
85
|
-
|
|
46
|
+
/**
|
|
47
|
+
* HOC to handle persistence and restoration of "Manage" components search parameters.
|
|
48
|
+
* Note: if you store a search date in a child component, make sure it’s called `date`.
|
|
49
|
+
* Rehydration of dates doesn’t work as expected out of the box with redux-persist.
|
|
50
|
+
* Something more generic might be in order in the future.
|
|
51
|
+
*
|
|
52
|
+
* Note: this also uses the `configureX` pattern of declaration for testability.
|
|
53
|
+
*
|
|
54
|
+
* API for child components:
|
|
55
|
+
* - Call `setSearchDefaults(this.doSearch, this.getDefaultSearch())` in child’s `componentDidMount`
|
|
56
|
+
* - Implement `getDefaultSearch`
|
|
57
|
+
* - Call this HOC’s handlers as needed
|
|
58
|
+
* - Implement any additional child-specific handlers and call this HOC’s `updateAndPersistSearch` in them
|
|
59
|
+
* - Make sure your `doSearch` and `render` handle undefined search props
|
|
60
|
+
* - Avoid intoxicating substances and wash your hands regularly
|
|
61
|
+
*
|
|
62
|
+
* @param WrappedComponent The component to wrap
|
|
63
|
+
* @param key The key under "search" in redux where the component’s search params will be stored
|
|
64
|
+
* @returns The wrapped component, passing down `search` and `persistSearch` as props
|
|
65
|
+
*/
|
|
66
|
+
export default function searchPersistorComponent<TOwnProps extends SearchPersistorWrappedProps<TSearchType>, TSearchType extends Search>(WrappedComponent: ComponentType<TOwnProps>, key: string): ComponentClass<Omit<TOwnProps, keyof SearchPersistorWrappedProps<TSearchType>>>;
|
|
@@ -168,26 +168,6 @@ var configureMapDispatchToProps = function (key) { return function (dispatch) {
|
|
|
168
168
|
};
|
|
169
169
|
}; };
|
|
170
170
|
exports.configureMapDispatchToProps = configureMapDispatchToProps;
|
|
171
|
-
/**
|
|
172
|
-
* HOC to handle persistence and restoration of "Manage" components search parameters.
|
|
173
|
-
* Note: if you store a search date in a child component, make sure it’s called `date`.
|
|
174
|
-
* Rehydration of dates doesn’t work as expected out of the box with redux-persist.
|
|
175
|
-
* Something more generic might be in order in the future.
|
|
176
|
-
*
|
|
177
|
-
* Note: this also uses the `configureX` pattern of declaration for testability.
|
|
178
|
-
*
|
|
179
|
-
* API for child components:
|
|
180
|
-
* - Call `setSearchDefaults(this.doSearch, this.getDefaultSearch())` in child’s `componentDidMount`
|
|
181
|
-
* - Implement `getDefaultSearch`
|
|
182
|
-
* - Call this HOC’s handlers as needed
|
|
183
|
-
* - Implement any additional child-specific handlers and call this HOC’s `updateAndPersistSearch` in them
|
|
184
|
-
* - Make sure your `doSearch` and `render` handle undefined search props
|
|
185
|
-
* - Avoid intoxicating substances and wash your hands regularly
|
|
186
|
-
*
|
|
187
|
-
* @param WrappedComponent The component to wrap
|
|
188
|
-
* @param key The key under "search" in redux where the component’s search params will be stored
|
|
189
|
-
* @returns The wrapped component, passing down `search` and `persistSearch` as props
|
|
190
|
-
*/
|
|
191
171
|
function searchPersistorComponent(WrappedComponent, key) {
|
|
192
172
|
var SearchPersistorComponent = configureSearchPersistorComponent(WrappedComponent);
|
|
193
173
|
var mapStateToProps = exports.configureMapStateToProps(key);
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { Component } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { RoleDescriptions } from '../../types';
|
|
3
3
|
export interface UserRolesAddProps {
|
|
4
4
|
id: string;
|
|
5
|
+
disabled?: boolean;
|
|
5
6
|
entityName?: string;
|
|
6
|
-
addUsersToRole: any;
|
|
7
|
-
shouldReset: boolean;
|
|
8
|
-
isAddingUsersToRole: boolean;
|
|
9
7
|
defaultRole: string;
|
|
10
|
-
roleDescriptions:
|
|
8
|
+
roleDescriptions: RoleDescriptions;
|
|
11
9
|
renderAddDescription?: (entityName?: string) => JSX.Element;
|
|
12
|
-
disabled?: boolean;
|
|
13
10
|
textForRole?: (role: string) => string;
|
|
11
|
+
isAddingUsersToRole: boolean;
|
|
12
|
+
shouldReset: boolean;
|
|
13
|
+
addUserRoles: (identifiers: string[], role: string) => void;
|
|
14
14
|
}
|
|
15
15
|
interface UserRolesAddState {
|
|
16
16
|
identifiers: string;
|
|
@@ -20,7 +20,7 @@ interface UserRolesAddState {
|
|
|
20
20
|
}
|
|
21
21
|
export default class UserRolesAdd extends Component<UserRolesAddProps, UserRolesAddState> {
|
|
22
22
|
constructor(props: UserRolesAddProps);
|
|
23
|
-
updateRole: (
|
|
23
|
+
updateRole: (role: string) => void;
|
|
24
24
|
componentDidUpdate(prevProps: UserRolesAddProps): void;
|
|
25
25
|
handleSubmit: () => void;
|
|
26
26
|
closeErrorAlert: () => void;
|
|
@@ -42,7 +42,7 @@ var react_1 = __importStar(require("react"));
|
|
|
42
42
|
var react_bootstrap_1 = require("react-bootstrap");
|
|
43
43
|
var AlertDialog_1 = __importDefault(require("../../components/AlertDialog"));
|
|
44
44
|
var Inline_1 = __importDefault(require("../../components/RefreshIndicator/Inline"));
|
|
45
|
-
var Select_1 =
|
|
45
|
+
var Select_1 = require("../../components/UserRoles/Select");
|
|
46
46
|
var baseRole_1 = __importDefault(require("../../constants/baseRole"));
|
|
47
47
|
var configuration_1 = require("../../constants/configuration");
|
|
48
48
|
var domainIdentifier_1 = require("../../utils/domainIdentifier");
|
|
@@ -54,9 +54,9 @@ var UserRolesAdd = /** @class */ (function (_super) {
|
|
|
54
54
|
__extends(UserRolesAdd, _super);
|
|
55
55
|
function UserRolesAdd(props) {
|
|
56
56
|
var _this = _super.call(this, props) || this;
|
|
57
|
-
_this.updateRole = function (
|
|
57
|
+
_this.updateRole = function (role) {
|
|
58
58
|
_this.setState({
|
|
59
|
-
role:
|
|
59
|
+
role: role
|
|
60
60
|
});
|
|
61
61
|
};
|
|
62
62
|
_this.handleSubmit = function () {
|
|
@@ -73,7 +73,7 @@ var UserRolesAdd = /** @class */ (function (_super) {
|
|
|
73
73
|
});
|
|
74
74
|
}
|
|
75
75
|
else {
|
|
76
|
-
_this.props.
|
|
76
|
+
_this.props.addUserRoles(identifiersArray, role);
|
|
77
77
|
}
|
|
78
78
|
};
|
|
79
79
|
_this.closeErrorAlert = function () {
|
|
@@ -140,7 +140,7 @@ var UserRolesAdd = /** @class */ (function (_super) {
|
|
|
140
140
|
" (separated by a new line)"),
|
|
141
141
|
react_1.default.createElement(react_bootstrap_1.FormControl, { type: "text", as: "textarea", name: "account", "aria-label": "The account names to add", onChange: this.updateIdentifiers, value: identifiers, placeholder: domainIdentifier_1.getDomainIdentifierTypeString(), disabled: disabled }))),
|
|
142
142
|
react_1.default.createElement(react_bootstrap_1.Col, { xs: 12, sm: 4 },
|
|
143
|
-
react_1.default.createElement(Select_1.
|
|
143
|
+
react_1.default.createElement(Select_1.RoleSelect, { options: roles, value: role, onChange: this.updateRole, labelVisible: true, popoverContentComponent: rolePopover, textForRole: textForRole })),
|
|
144
144
|
react_1.default.createElement(react_bootstrap_1.Col, { xs: 12, sm: 2, className: "mt3-ns pt2-ns" },
|
|
145
145
|
isAddingUsersToRole && react_1.default.createElement(Inline_1.default, { className: "mr3" }),
|
|
146
146
|
!isAddingUsersToRole && (react_1.default.createElement(Button_1.default, { id: "userRolesAddButton", className: "btn btn-primary w-100-lt-xs", disabled: !identifiers || disabled, color: "primary", onClick: this.handleSubmit },
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { UserRole } from '../../types';
|
|
3
|
+
export interface UserRolesContextType {
|
|
4
|
+
/** disable all user role select dropdowns, if any */
|
|
5
|
+
isUpdateDisabled?: boolean;
|
|
6
|
+
/** disable all user role delete buttons */
|
|
7
|
+
isDeleteDisabled?: boolean;
|
|
8
|
+
/** Is the current user allowed to add, update, and delete user roles? */
|
|
9
|
+
canModify?: boolean;
|
|
10
|
+
/** Is the current user allowed to delete their own user role? */
|
|
11
|
+
canDeleteSelf?: boolean;
|
|
12
|
+
/** If multiple roles allowed, each role is displayed per user, otherwise a select dropdown is displayed. */
|
|
13
|
+
allowMultipleRoles?: boolean;
|
|
14
|
+
roles: string[];
|
|
15
|
+
/** (Optional) If provided, the last user role with the required role will be prevented from being removed. */
|
|
16
|
+
requiredRole?: string;
|
|
17
|
+
/** (Optional) Provide custom user-friendly names for displayed roles */
|
|
18
|
+
textForRole?: (role: string) => string;
|
|
19
|
+
/** The user role being updated */
|
|
20
|
+
userRoleToUpdate?: UserRole;
|
|
21
|
+
/** If a user role is being updated */
|
|
22
|
+
isUpdating: boolean;
|
|
23
|
+
/** Method to update a user role */
|
|
24
|
+
updateUserRole: (userRoleToUpdate: UserRole, newRole: string) => void;
|
|
25
|
+
/** The user role being removed */
|
|
26
|
+
userRoleToRemove?: UserRole;
|
|
27
|
+
/** If a user role is being removed */
|
|
28
|
+
isRemoving: boolean;
|
|
29
|
+
/** Method to remove a user role */
|
|
30
|
+
removeUserRole: (userRoleToRemove: UserRole) => void;
|
|
31
|
+
}
|
|
32
|
+
export declare const UserRolesContext: React.Context<UserRolesContextType>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.UserRolesContext = void 0;
|
|
7
|
+
var react_1 = __importDefault(require("react"));
|
|
8
|
+
/*
|
|
9
|
+
* Context provided to the children of UserRoles. Default values should be initialized
|
|
10
|
+
* by the context provider.
|
|
11
|
+
*/
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
13
|
+
exports.UserRolesContext = react_1.default.createContext(undefined);
|
|
@@ -1,21 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { BaseReduxState } from '../../types/BaseReduxState';
|
|
1
|
+
import { FunctionComponent } from 'react';
|
|
3
2
|
import { UserWithRoles } from '../../types/UserRole';
|
|
4
|
-
export interface
|
|
3
|
+
export interface RoleCellProps {
|
|
5
4
|
user: UserWithRoles;
|
|
6
|
-
|
|
7
|
-
canModifySelf?: boolean;
|
|
8
|
-
textForRole?: (role: string) => string;
|
|
9
|
-
removeUserFromRole?: (user: UserWithRoles, role: string) => void;
|
|
10
|
-
roles: string[];
|
|
11
|
-
entityOwnerRole: string;
|
|
12
|
-
}
|
|
13
|
-
export interface RoleCellReduxProps {
|
|
14
|
-
currentUserId: string;
|
|
15
|
-
}
|
|
16
|
-
export interface RoleCellProps extends RoleCellOwnProps, RoleCellReduxProps {
|
|
5
|
+
requiredRoleCount?: number;
|
|
17
6
|
}
|
|
18
7
|
export declare const RoleCell: FunctionComponent<RoleCellProps>;
|
|
19
|
-
export declare const mapStateToProps: (state: BaseReduxState) => RoleCellReduxProps;
|
|
20
|
-
declare const _default: import("react-redux").ConnectedComponent<React.FunctionComponent<RoleCellProps>, Pick<RoleCellProps, "user" | "readOnly" | "textForRole" | "canModifySelf" | "removeUserFromRole" | "roles" | "entityOwnerRole">>;
|
|
21
|
-
export default _default;
|
|
@@ -1,34 +1,97 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
2
21
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
22
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
23
|
};
|
|
5
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
25
|
+
exports.RoleCell = void 0;
|
|
7
26
|
var core_1 = require("@material-ui/core");
|
|
8
27
|
var Delete_1 = __importDefault(require("@material-ui/icons/Delete"));
|
|
9
|
-
var react_1 =
|
|
28
|
+
var react_1 = __importStar(require("react"));
|
|
10
29
|
var react_bootstrap_1 = require("react-bootstrap");
|
|
11
30
|
var react_redux_1 = require("react-redux");
|
|
12
31
|
var userRole_1 = require("../../utils/userRole");
|
|
13
32
|
var IconExternalUser_1 = require("../Icons/IconExternalUser");
|
|
33
|
+
var Inline_1 = __importDefault(require("../RefreshIndicator/Inline"));
|
|
34
|
+
var Context_1 = require("./Context");
|
|
35
|
+
var Select_1 = require("./Select");
|
|
14
36
|
var RoleCell = function (_a) {
|
|
15
|
-
var user = _a.user,
|
|
37
|
+
var user = _a.user, requiredRoleCount = _a.requiredRoleCount;
|
|
38
|
+
var _b = react_1.useContext(Context_1.UserRolesContext), isUpdateDisabled = _b.isUpdateDisabled, isDeleteDisabled = _b.isDeleteDisabled, canModify = _b.canModify, canDeleteSelf = _b.canDeleteSelf, allowMultipleRoles = _b.allowMultipleRoles, roles = _b.roles, requiredRole = _b.requiredRole, textForRole = _b.textForRole, userRoleToUpdate = _b.userRoleToUpdate, isUpdating = _b.isUpdating, updateUserRole = _b.updateUserRole, userRoleToRemove = _b.userRoleToRemove, isRemoving = _b.isRemoving, removeUserRole = _b.removeUserRole;
|
|
39
|
+
var currentUserId = react_redux_1.useSelector(function (state) {
|
|
40
|
+
if (!state.models.user || !state.models.user.userInfo) {
|
|
41
|
+
throw new Error('Current user id is not stored in redux');
|
|
42
|
+
}
|
|
43
|
+
return state.models.user.userInfo.id;
|
|
44
|
+
});
|
|
16
45
|
return (react_1.default.createElement("ul", { className: "mb0 list pa0 tr" }, user.roles.sort(userRole_1.sortByRole(roles)).map(function (userRole) {
|
|
17
46
|
var roleText = userRole_1.getRoleText(textForRole)(userRole);
|
|
18
47
|
var isUserRoleExternal = userRole_1.isExternal(userRole);
|
|
19
|
-
var
|
|
48
|
+
var userId = userRole_1.getUserId(userRole);
|
|
49
|
+
var canUpdate =
|
|
50
|
+
// current user has modify access
|
|
51
|
+
canModify &&
|
|
52
|
+
// in single role mode (multiple roles are not allowed)
|
|
53
|
+
!allowMultipleRoles &&
|
|
54
|
+
// the userRole is not external (roster synced)
|
|
55
|
+
!isUserRoleExternal &&
|
|
56
|
+
// update is not disabled
|
|
57
|
+
!isUpdateDisabled &&
|
|
58
|
+
// there is more than one possible role
|
|
59
|
+
roles.length > 1 &&
|
|
60
|
+
// the user role is not the last remaining required role user
|
|
61
|
+
(!requiredRole || userRole.role !== requiredRole || !requiredRoleCount || requiredRoleCount > 1);
|
|
62
|
+
var canDelete =
|
|
63
|
+
// the userRole is not external (roster synced)
|
|
64
|
+
!isUserRoleExternal &&
|
|
65
|
+
// delete is not disabled, e.g. course is ended
|
|
66
|
+
!isDeleteDisabled &&
|
|
67
|
+
// the role is not the last required role
|
|
68
|
+
(!requiredRole || userRole.role !== requiredRole || !requiredRoleCount || requiredRoleCount > 1) &&
|
|
69
|
+
// the current user can delete the role for another user, or the current user can delete themselves
|
|
70
|
+
((canModify && user.id !== currentUserId) || (canDeleteSelf && user.id === currentUserId));
|
|
71
|
+
var shouldDisplayRightAligned =
|
|
72
|
+
// in multiple role mode
|
|
73
|
+
allowMultipleRoles ||
|
|
74
|
+
// only one role option
|
|
75
|
+
roles.length === 1 ||
|
|
76
|
+
// no access to update
|
|
77
|
+
!canModify ||
|
|
78
|
+
// update is disabled
|
|
79
|
+
isUpdateDisabled;
|
|
80
|
+
var isExternalPopover = (react_1.default.createElement(react_bootstrap_1.Popover, { id: "is-external-popover-" + userId + "-" + userRole.role },
|
|
20
81
|
react_1.default.createElement("h3", null, "Added via Roster Sync"),
|
|
21
82
|
react_1.default.createElement("p", { className: "mb2" }, "This person was added automatically via roster sync and cannot be manually removed.")));
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
|
|
83
|
+
var isUserRoleUpdating = isUpdating && (userRoleToUpdate === null || userRoleToUpdate === void 0 ? void 0 : userRoleToUpdate.id) === userRole.id;
|
|
84
|
+
var isUserRoleRemoving = isRemoving && (userRoleToRemove === null || userRoleToRemove === void 0 ? void 0 : userRoleToRemove.id) === userRole.id;
|
|
85
|
+
return (react_1.default.createElement("li", { key: user.id + "-" + roleText, className: "nowrap flex items-center" + (shouldDisplayRightAligned ? ' justify-end' : '') },
|
|
86
|
+
isUserRoleUpdating ? (react_1.default.createElement("div", { className: "flex justify-start flex-grow-1 pl3" },
|
|
87
|
+
react_1.default.createElement(Inline_1.default, { size: 20 }))) : canUpdate ? (react_1.default.createElement(Select_1.RoleSelectControl, { options: roles, value: userRole.role, onChange: function (role) {
|
|
88
|
+
updateUserRole(userRole, role);
|
|
89
|
+
}, textForRole: textForRole, disabled: isUpdating || isRemoving })) : (react_1.default.createElement("span", { className: shouldDisplayRightAligned ? '' : 'pl3' }, roleText)),
|
|
90
|
+
isUserRoleRemoving ? (react_1.default.createElement("div", { className: "flex items-center" },
|
|
91
|
+
react_1.default.createElement(Inline_1.default, { size: 20, className: "ma3" }))) : canDelete ? (react_1.default.createElement(core_1.IconButton, { className: "remove-user-button", "aria-label": "Remove " + roleText, onClick: function () {
|
|
92
|
+
removeUserRole(userRole);
|
|
93
|
+
}, disabled: isUpdating || isRemoving },
|
|
94
|
+
react_1.default.createElement(Delete_1.default, { color: "error" }))) : isUserRoleExternal ? (react_1.default.createElement(react_bootstrap_1.OverlayTrigger, { placement: "auto", trigger: ['click', 'hover', 'focus'], overlay: isExternalPopover },
|
|
32
95
|
react_1.default.createElement(IconExternalUser_1.IconExternalUser, { tabIndex: 0, style: { margin: '12px', opacity: 0.5 }, className: "external-icon" }))) : (
|
|
33
96
|
// dummy spacer to keep items aligned
|
|
34
97
|
react_1.default.createElement("span", { style: {
|
|
@@ -41,13 +104,3 @@ var RoleCell = function (_a) {
|
|
|
41
104
|
})));
|
|
42
105
|
};
|
|
43
106
|
exports.RoleCell = RoleCell;
|
|
44
|
-
var mapStateToProps = function (state) {
|
|
45
|
-
if (!state.models.user || !state.models.user.userInfo) {
|
|
46
|
-
throw new Error('Current user id is not stored in redux');
|
|
47
|
-
}
|
|
48
|
-
return {
|
|
49
|
-
currentUserId: state.models.user.userInfo.id
|
|
50
|
-
};
|
|
51
|
-
};
|
|
52
|
-
exports.mapStateToProps = mapStateToProps;
|
|
53
|
-
exports.default = react_redux_1.connect(exports.mapStateToProps)(exports.RoleCell);
|
|
@@ -1,27 +1,26 @@
|
|
|
1
|
-
import { ReactElement } from 'react';
|
|
1
|
+
import { FunctionComponent, ReactElement } from 'react';
|
|
2
2
|
import { OverlayInjectedProps } from 'react-bootstrap/Overlay';
|
|
3
|
-
export interface
|
|
3
|
+
export interface RoleSelectControlProps {
|
|
4
|
+
/** CSS class passed to the selector FormControl component */
|
|
4
5
|
className?: string;
|
|
6
|
+
/** Array of options the user can choose from */
|
|
5
7
|
options: string[];
|
|
8
|
+
/** Currently selected value */
|
|
6
9
|
value: string;
|
|
7
|
-
|
|
10
|
+
/** Function that is called when the value changes */
|
|
11
|
+
onChange: (option: string) => void;
|
|
12
|
+
/** (Optional) Provide custom user-friendly names for displayed roles */
|
|
13
|
+
textForRole?: (role: string) => string;
|
|
14
|
+
/** (Optional) Is the control disabled? */
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare const RoleSelectControl: FunctionComponent<RoleSelectControlProps>;
|
|
18
|
+
export interface RoleSelectProps extends RoleSelectControlProps {
|
|
19
|
+
/** Id for the 'select' form control, defaults to 'RoleSelect' */
|
|
8
20
|
controlId?: string;
|
|
21
|
+
/** Whether the label text should be visible */
|
|
9
22
|
labelVisible?: boolean;
|
|
23
|
+
/** (Optional) Content of the popover tooltip */
|
|
10
24
|
popoverContentComponent?: ReactElement<OverlayInjectedProps>;
|
|
11
|
-
textForRole?: (role: string) => string;
|
|
12
25
|
}
|
|
13
|
-
|
|
14
|
-
* Create a selector which will be properly labeled based on the number of options and provided content.
|
|
15
|
-
*
|
|
16
|
-
* @param {string} props.className - CSS class passed to the selector FormControl component
|
|
17
|
-
* @param {string[]} props.options - Array of options the user can choose from
|
|
18
|
-
* @param {string} props.value - Currently selected value
|
|
19
|
-
* @param {function} props.onChange - Function that is called when the value changes
|
|
20
|
-
* @param {string} props.controlId - Id for the selector
|
|
21
|
-
* @param {boolean} props.labelVisible - Whether the label text should be visible
|
|
22
|
-
* @param {ReactNode} props.popoverContentComponent - Content of the popover tooltip
|
|
23
|
-
*
|
|
24
|
-
* @returns {ReactElement} Selector and label component
|
|
25
|
-
*/
|
|
26
|
-
declare const RoleSelect: (props: RoleSelectProps) => JSX.Element;
|
|
27
|
-
export default RoleSelect;
|
|
26
|
+
export declare const RoleSelect: FunctionComponent<RoleSelectProps>;
|
|
@@ -1,8 +1,31 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
14
|
+
var t = {};
|
|
15
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
16
|
+
t[p] = s[p];
|
|
17
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
18
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
19
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
20
|
+
t[p[i]] = s[p[i]];
|
|
21
|
+
}
|
|
22
|
+
return t;
|
|
23
|
+
};
|
|
2
24
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
25
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
26
|
};
|
|
5
27
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
+
exports.RoleSelect = exports.RoleSelectControl = void 0;
|
|
6
29
|
var Help_1 = __importDefault(require("@material-ui/icons/Help"));
|
|
7
30
|
var react_1 = __importDefault(require("react"));
|
|
8
31
|
var react_bootstrap_1 = require("react-bootstrap");
|
|
@@ -18,27 +41,18 @@ var overlay = function (hasMultipleOptions, labelVisible, rolePopover) {
|
|
|
18
41
|
if (labelVisible === void 0) { labelVisible = false; }
|
|
19
42
|
return rolePopover ? (react_1.default.createElement(react_bootstrap_1.OverlayTrigger, { placement: "right", trigger: ['click', 'hover', 'focus'], overlay: rolePopover }, label(hasMultipleOptions, labelVisible, true))) : (label(hasMultipleOptions, labelVisible, false));
|
|
20
43
|
};
|
|
21
|
-
var
|
|
22
|
-
|
|
44
|
+
var RoleSelectControl = function (_a) {
|
|
45
|
+
var className = _a.className, options = _a.options, value = _a.value, onChange = _a.onChange, textForRole = _a.textForRole, disabled = _a.disabled;
|
|
46
|
+
return options.length > 1 ? (react_1.default.createElement(react_bootstrap_1.FormControl, { className: className ? className : '', "aria-label": "Role", as: "select", placeholder: "select", onChange: function (e) {
|
|
47
|
+
onChange(e.target.value);
|
|
48
|
+
}, value: value, disabled: disabled }, options.map(function (role, i) { return (react_1.default.createElement("option", { value: role, key: role }, textForRole ? textForRole(role) : baseRole_1.textForBaseRole(role))); }))) : (react_1.default.createElement("div", null, textForRole ? textForRole(options[0]) : baseRole_1.textForBaseRole(options[0])));
|
|
23
49
|
};
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
* @param {string} props.className - CSS class passed to the selector FormControl component
|
|
28
|
-
* @param {string[]} props.options - Array of options the user can choose from
|
|
29
|
-
* @param {string} props.value - Currently selected value
|
|
30
|
-
* @param {function} props.onChange - Function that is called when the value changes
|
|
31
|
-
* @param {string} props.controlId - Id for the selector
|
|
32
|
-
* @param {boolean} props.labelVisible - Whether the label text should be visible
|
|
33
|
-
* @param {ReactNode} props.popoverContentComponent - Content of the popover tooltip
|
|
34
|
-
*
|
|
35
|
-
* @returns {ReactElement} Selector and label component
|
|
36
|
-
*/
|
|
37
|
-
var RoleSelect = function (props) {
|
|
38
|
-
var className = props.className, options = props.options, value = props.value, onChange = props.onChange, controlId = props.controlId, labelVisible = props.labelVisible, popoverContentComponent = props.popoverContentComponent, textForRole = props.textForRole;
|
|
50
|
+
exports.RoleSelectControl = RoleSelectControl;
|
|
51
|
+
var RoleSelect = function (_a) {
|
|
52
|
+
var controlId = _a.controlId, labelVisible = _a.labelVisible, popoverContentComponent = _a.popoverContentComponent, options = _a.options, controlProps = __rest(_a, ["controlId", "labelVisible", "popoverContentComponent", "options"]);
|
|
39
53
|
var content = (react_1.default.createElement(react_1.default.Fragment, null,
|
|
40
54
|
overlay(options.length > 1, !!labelVisible, popoverContentComponent),
|
|
41
|
-
|
|
55
|
+
react_1.default.createElement(exports.RoleSelectControl, __assign({ options: options }, controlProps))));
|
|
42
56
|
return options.length > 1 ? (react_1.default.createElement(react_bootstrap_1.FormGroup, { controlId: controlId ? controlId : 'RoleSelect' }, content)) : (react_1.default.createElement("span", null, content));
|
|
43
57
|
};
|
|
44
|
-
exports.
|
|
58
|
+
exports.RoleSelect = RoleSelect;
|
|
@@ -3,14 +3,5 @@ import { UserWithRoles } from '../../types';
|
|
|
3
3
|
export interface UserRolesTableProps {
|
|
4
4
|
id?: string;
|
|
5
5
|
users: UserWithRoles[];
|
|
6
|
-
readOnly?: boolean;
|
|
7
|
-
canModifySelf?: boolean;
|
|
8
|
-
removeUserFromRole?: (user: UserWithRoles, role: string) => void;
|
|
9
|
-
textForRole?: (role: string) => string;
|
|
10
|
-
roles: string[];
|
|
11
|
-
/** The role for the owner of the entity, i.e. GroupOwner, RubricOwner, ProblemOwner etc.
|
|
12
|
-
** The current user cannot be removed from an ownership role unless they are an admin.
|
|
13
|
-
**/
|
|
14
|
-
entityOwnerRole: string;
|
|
15
6
|
}
|
|
16
7
|
export declare const UserRolesTable: React.NamedExoticComponent<UserRolesTableProps>;
|
|
@@ -29,9 +29,11 @@ var react_table_1 = __importDefault(require("react-table"));
|
|
|
29
29
|
var userRole_1 = require("../../utils/userRole");
|
|
30
30
|
var RoleFilter_1 = require("../Tables/RoleFilter");
|
|
31
31
|
var TextFilter_1 = require("../Tables/TextFilter");
|
|
32
|
-
var
|
|
32
|
+
var Context_1 = require("./Context");
|
|
33
|
+
var RoleCell_1 = require("./RoleCell");
|
|
33
34
|
var UserRolesTableComponent = function (_a) {
|
|
34
|
-
var id = _a.id, users = _a.users
|
|
35
|
+
var id = _a.id, users = _a.users;
|
|
36
|
+
var _b = react_1.useContext(Context_1.UserRolesContext), roles = _b.roles, requiredRole = _b.requiredRole, textForRole = _b.textForRole;
|
|
35
37
|
var hasExternal = users.some(function (r) { return r.roles.some(function (r) { return userRole_1.isExternal(r); }); });
|
|
36
38
|
var columns = [
|
|
37
39
|
{
|
|
@@ -60,7 +62,9 @@ var UserRolesTableComponent = function (_a) {
|
|
|
60
62
|
accessor: function (u) { return u; },
|
|
61
63
|
Cell: function (cell) {
|
|
62
64
|
var user = cell.value;
|
|
63
|
-
return (react_1.default.createElement(RoleCell_1.
|
|
65
|
+
return (react_1.default.createElement(RoleCell_1.RoleCell, { user: user, requiredRoleCount: requiredRole
|
|
66
|
+
? users.filter(function (u) { return u.roles.some(function (r) { return r.role === requiredRole; }); }).length
|
|
67
|
+
: undefined }));
|
|
64
68
|
},
|
|
65
69
|
filterMethod: RoleFilter_1.roleFilterMethod,
|
|
66
70
|
Filter: RoleFilter_1.RoleFilter(roles, textForRole, hasExternal),
|
|
@@ -68,21 +72,27 @@ var UserRolesTableComponent = function (_a) {
|
|
|
68
72
|
style: { padding: '4px' }
|
|
69
73
|
});
|
|
70
74
|
}
|
|
71
|
-
var
|
|
75
|
+
var _c = react_1.useState(users), usersState = _c[0], setUsersState = _c[1];
|
|
76
|
+
var _d = react_1.useState(), roleFilter = _d[0], setRoleFilter = _d[1];
|
|
72
77
|
var onFilteredChange = function (newFiltering, column, value) {
|
|
78
|
+
var newRoleFilter = newFiltering.find(function (f) { return f.id === 'role'; });
|
|
79
|
+
setRoleFilter(newRoleFilter);
|
|
80
|
+
};
|
|
81
|
+
// update `usersState` when `users` or `roleFilter` changes
|
|
82
|
+
react_1.useEffect(function () {
|
|
83
|
+
var usersToDisplay = users;
|
|
73
84
|
// when the role filter is set, only show the matching userRoles in the table
|
|
74
|
-
var roleFilter = newFiltering.find(function (f) { return f.id === 'role'; });
|
|
75
85
|
if (roleFilter) {
|
|
76
|
-
|
|
86
|
+
usersToDisplay = users.map(function (u) {
|
|
77
87
|
var newUser = lodash_1.merge({}, u);
|
|
78
88
|
newUser.roles = u.roles.filter(function (r) { return RoleFilter_1.roleUserRoleFilterMethod(roleFilter, r); });
|
|
79
89
|
return newUser;
|
|
80
|
-
})
|
|
90
|
+
});
|
|
81
91
|
}
|
|
82
|
-
|
|
83
|
-
setUsersState(
|
|
92
|
+
if (!lodash_1.isEqual(usersToDisplay, usersState)) {
|
|
93
|
+
setUsersState(usersToDisplay);
|
|
84
94
|
}
|
|
85
|
-
};
|
|
95
|
+
}, [users, roleFilter, usersState]);
|
|
86
96
|
return (react_1.default.createElement("div", { id: id, className: "table-container" },
|
|
87
97
|
react_1.default.createElement(react_table_1.default, { className: "-striped", columns: columns, data: usersState, resizable: false, filterable: true, onFilteredChange: onFilteredChange, defaultSorted: [
|
|
88
98
|
{
|
|
@@ -93,7 +103,7 @@ var UserRolesTableComponent = function (_a) {
|
|
|
93
103
|
id: 'firstName',
|
|
94
104
|
desc: false
|
|
95
105
|
}
|
|
96
|
-
],
|
|
106
|
+
], pageSize: Object.keys(usersState).length, showPagination: false })));
|
|
97
107
|
};
|
|
98
108
|
// similar to "shouldComponentUpdate", prevent unnecessary renders
|
|
99
|
-
exports.UserRolesTable = react_1.default.memo(UserRolesTableComponent, function (prevProps, nextProps) { return
|
|
109
|
+
exports.UserRolesTable = react_1.default.memo(UserRolesTableComponent, function (prevProps, nextProps) { return lodash_1.isEqual(prevProps, nextProps); });
|