studiokit-scaffolding-js 4.3.20 → 4.4.0

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.
@@ -2,8 +2,9 @@ import { Component } from 'react';
2
2
  import { RoleDescription } from '../../types';
3
3
  export interface UserRolesAddProps {
4
4
  id: string;
5
+ /** optional, if not targeting entityUserRoles */
5
6
  entityName?: string;
6
- addUsersToRole: any;
7
+ addUsersToRole: (identifiers: string[], role: string) => void;
7
8
  shouldReset: boolean;
8
9
  isAddingUsersToRole: boolean;
9
10
  defaultRole: string;
@@ -1,12 +1,12 @@
1
1
  import React, { FunctionComponent } from 'react';
2
2
  import { BaseReduxState } from '../../types/BaseReduxState';
3
- import { UserWithRoles } from '../../types/UserRole';
3
+ import { UserRole, UserWithRoles } from '../../types/UserRole';
4
4
  export interface RoleCellOwnProps {
5
5
  user: UserWithRoles;
6
6
  readOnly?: boolean;
7
7
  canModifySelf?: boolean;
8
8
  textForRole?: (role: string) => string;
9
- removeUserFromRole?: (user: UserWithRoles, role: string) => void;
9
+ removeUserRole?: (user: UserRole) => void;
10
10
  roles: string[];
11
11
  entityOwnerRole: string;
12
12
  }
@@ -17,5 +17,5 @@ export interface RoleCellProps extends RoleCellOwnProps, RoleCellReduxProps {
17
17
  }
18
18
  export declare const RoleCell: FunctionComponent<RoleCellProps>;
19
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">>;
20
+ declare const _default: import("react-redux").ConnectedComponent<React.FunctionComponent<RoleCellProps>, Pick<RoleCellProps, "user" | "readOnly" | "textForRole" | "canModifySelf" | "removeUserRole" | "roles" | "entityOwnerRole">>;
21
21
  export default _default;
@@ -12,11 +12,12 @@ var react_redux_1 = require("react-redux");
12
12
  var userRole_1 = require("../../utils/userRole");
13
13
  var IconExternalUser_1 = require("../Icons/IconExternalUser");
14
14
  var RoleCell = function (_a) {
15
- var user = _a.user, currentUserId = _a.currentUserId, readOnly = _a.readOnly, canModifySelf = _a.canModifySelf, textForRole = _a.textForRole, removeUserFromRole = _a.removeUserFromRole, roles = _a.roles, entityOwnerRole = _a.entityOwnerRole;
15
+ var user = _a.user, currentUserId = _a.currentUserId, readOnly = _a.readOnly, canModifySelf = _a.canModifySelf, textForRole = _a.textForRole, removeUserRole = _a.removeUserRole, roles = _a.roles, entityOwnerRole = _a.entityOwnerRole;
16
16
  return (react_1.default.createElement("ul", { className: "mb0 list pa0 tr" }, user.roles.sort(userRole_1.sortByRole(roles)).map(function (userRole) {
17
17
  var roleText = userRole_1.getRoleText(textForRole)(userRole);
18
18
  var isUserRoleExternal = userRole_1.isExternal(userRole);
19
- var popover = (react_1.default.createElement(react_bootstrap_1.Popover, { id: "is-external-popover-" + userRole.userId + "-" + userRole.role },
19
+ var userId = userRole_1.getUserId(userRole);
20
+ var popover = (react_1.default.createElement(react_bootstrap_1.Popover, { id: "is-external-popover-" + userId + "-" + userRole.role },
20
21
  react_1.default.createElement("h3", null, "Added via Roster Sync"),
21
22
  react_1.default.createElement("p", { className: "mb2" }, "This person was added automatically via roster sync and cannot be manually removed.")));
22
23
  return (react_1.default.createElement("li", { key: user.id + "-" + roleText, className: "nowrap" },
@@ -24,8 +25,8 @@ var RoleCell = function (_a) {
24
25
  !isUserRoleExternal &&
25
26
  !readOnly &&
26
27
  (user.id !== currentUserId || canModifySelf || userRole.role !== entityOwnerRole) ? (react_1.default.createElement(core_1.IconButton, { className: "remove-user-button", "aria-label": "Remove " + roleText, onClick: function () {
27
- if (removeUserFromRole) {
28
- removeUserFromRole(user, userRole.role);
28
+ if (removeUserRole) {
29
+ removeUserRole(userRole);
29
30
  }
30
31
  } },
31
32
  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: popover },
@@ -1,11 +1,11 @@
1
1
  import React from 'react';
2
- import { UserWithRoles } from '../../types';
2
+ import { UserRole, UserWithRoles } from '../../types';
3
3
  export interface UserRolesTableProps {
4
4
  id?: string;
5
5
  users: UserWithRoles[];
6
6
  readOnly?: boolean;
7
7
  canModifySelf?: boolean;
8
- removeUserFromRole?: (user: UserWithRoles, role: string) => void;
8
+ removeUserRole?: (userRole: UserRole) => void;
9
9
  textForRole?: (role: string) => string;
10
10
  roles: string[];
11
11
  /** The role for the owner of the entity, i.e. GroupOwner, RubricOwner, ProblemOwner etc.
@@ -31,7 +31,7 @@ var RoleFilter_1 = require("../Tables/RoleFilter");
31
31
  var TextFilter_1 = require("../Tables/TextFilter");
32
32
  var RoleCell_1 = __importDefault(require("./RoleCell"));
33
33
  var UserRolesTableComponent = function (_a) {
34
- var id = _a.id, users = _a.users, roles = _a.roles, readOnly = _a.readOnly, canModifySelf = _a.canModifySelf, textForRole = _a.textForRole, removeUserFromRole = _a.removeUserFromRole, entityOwnerRole = _a.entityOwnerRole;
34
+ var id = _a.id, users = _a.users, roles = _a.roles, readOnly = _a.readOnly, canModifySelf = _a.canModifySelf, textForRole = _a.textForRole, removeUserRole = _a.removeUserRole, entityOwnerRole = _a.entityOwnerRole;
35
35
  var hasExternal = users.some(function (r) { return r.roles.some(function (r) { return userRole_1.isExternal(r); }); });
36
36
  var columns = [
37
37
  {
@@ -60,7 +60,7 @@ var UserRolesTableComponent = function (_a) {
60
60
  accessor: function (u) { return u; },
61
61
  Cell: function (cell) {
62
62
  var user = cell.value;
63
- return (react_1.default.createElement(RoleCell_1.default, { user: user, readOnly: readOnly, canModifySelf: canModifySelf, textForRole: textForRole, removeUserFromRole: removeUserFromRole, roles: roles, entityOwnerRole: entityOwnerRole }));
63
+ return (react_1.default.createElement(RoleCell_1.default, { user: user, readOnly: readOnly, canModifySelf: canModifySelf, textForRole: textForRole, removeUserRole: removeUserRole, roles: roles, entityOwnerRole: entityOwnerRole }));
64
64
  },
65
65
  filterMethod: RoleFilter_1.roleFilterMethod,
66
66
  Filter: RoleFilter_1.RoleFilter(roles, textForRole, hasExternal),
@@ -69,20 +69,26 @@ var UserRolesTableComponent = function (_a) {
69
69
  });
70
70
  }
71
71
  var _b = react_1.useState(users), usersState = _b[0], setUsersState = _b[1];
72
+ var _c = react_1.useState(), roleFilter = _c[0], setRoleFilter = _c[1];
72
73
  var onFilteredChange = function (newFiltering, column, value) {
74
+ var newRoleFilter = newFiltering.find(function (f) { return f.id === 'role'; });
75
+ setRoleFilter(newRoleFilter);
76
+ };
77
+ // update `usersState` when `users` or `roleFilter` changes
78
+ react_1.useEffect(function () {
79
+ var usersToDisplay = users;
73
80
  // 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
81
  if (roleFilter) {
76
- setUsersState(users.map(function (u) {
82
+ usersToDisplay = users.map(function (u) {
77
83
  var newUser = lodash_1.merge({}, u);
78
84
  newUser.roles = u.roles.filter(function (r) { return RoleFilter_1.roleUserRoleFilterMethod(roleFilter, r); });
79
85
  return newUser;
80
- }));
86
+ });
81
87
  }
82
- else if (!lodash_1.isEqual(users, usersState)) {
83
- setUsersState(users);
88
+ if (!lodash_1.isEqual(usersToDisplay, usersState)) {
89
+ setUsersState(usersToDisplay);
84
90
  }
85
- };
91
+ }, [users, roleFilter, usersState]);
86
92
  return (react_1.default.createElement("div", { id: id, className: "table-container" },
87
93
  react_1.default.createElement(react_table_1.default, { className: "-striped", columns: columns, data: usersState, resizable: false, filterable: true, onFilteredChange: onFilteredChange, defaultSorted: [
88
94
  {
@@ -93,7 +99,7 @@ var UserRolesTableComponent = function (_a) {
93
99
  id: 'firstName',
94
100
  desc: false
95
101
  }
96
- ], defaultPageSize: Object.keys(usersState).length, showPagination: false })));
102
+ ], pageSize: Object.keys(usersState).length, showPagination: false })));
97
103
  };
98
104
  // similar to "shouldComponentUpdate", prevent unnecessary renders
99
- exports.UserRolesTable = react_1.default.memo(UserRolesTableComponent, function (prevProps, nextProps) { return !lodash_1.isEqual(prevProps, nextProps); });
105
+ exports.UserRolesTable = react_1.default.memo(UserRolesTableComponent, function (prevProps, nextProps) { return lodash_1.isEqual(prevProps, nextProps); });
@@ -1,15 +1,14 @@
1
1
  import React, { Component } from 'react';
2
2
  import { FetchError, Model, ModelCollection } from 'studiokit-net-js';
3
- import BASE_ROLE from '../../constants/baseRole';
4
- import { BaseReduxState, ExternalProvider, RoleDescription, User, UserWithRoles } from '../../types';
3
+ import { BaseReduxState, ExternalProvider, RoleDescription, UserRole, UserWithRoles } from '../../types';
5
4
  import { CollectionComponentWrappedProps } from '../HOC/CollectionComponent';
6
5
  export interface UserRolesReduxProps {
7
6
  canModifySelf?: boolean;
8
7
  canModify?: boolean;
9
8
  }
10
- export interface UserRolesOwnProps extends CollectionComponentWrappedProps<UserWithRoles> {
9
+ export interface UserRolesOwnProps extends CollectionComponentWrappedProps<UserRole> {
11
10
  modifyUserRoleActivityName: string;
12
- filterUsers: (userRoles: UserWithRoles[]) => UserWithRoles[];
11
+ filterUsers: (users: UserWithRoles[]) => UserWithRoles[];
13
12
  /** The role that will be shown first in the list of available roles. Currently assumes that this is the entity owner role, groupOwner, assignmentOwner, rubricOwner, problemOwner etc. */
14
13
  defaultRole: string;
15
14
  /** A dictionary of all possible roles and their descriptions. */
@@ -28,6 +27,7 @@ export interface UserRolesOwnProps extends CollectionComponentWrappedProps<UserW
28
27
  isDeleteDisabled?: boolean;
29
28
  /** An optional parameter for `renderRemoveUserDescription` */
30
29
  externalProviders?: ModelCollection<ExternalProvider>;
30
+ allowMultipleRoles?: boolean;
31
31
  }
32
32
  export interface UserRolesProps extends UserRolesReduxProps, UserRolesOwnProps {
33
33
  }
@@ -38,16 +38,17 @@ interface UserRolesState {
38
38
  identifiersToAdd?: string[];
39
39
  roleForAdd?: string;
40
40
  shouldResetAddForm: boolean;
41
+ userRoleToUpdate: UserRole | undefined;
42
+ roleForUpdate?: string;
41
43
  shouldShowRemoveDialog: boolean;
42
- userToRemove: UserWithRoles | undefined;
43
- roleForRemove?: string;
44
+ userRoleToRemove: UserRole | undefined;
44
45
  successMessage?: string;
45
- existingUsersMessage?: string;
46
+ existingMessage?: string;
46
47
  failMessage?: string;
47
48
  }
48
49
  export interface AddBusinessModel {
49
- addedUsers: UserWithRoles[];
50
- existingUsers: UserWithRoles[];
50
+ addedUserRoles: UserRole[];
51
+ existingUserRoles: UserRole[];
51
52
  invalidIdentifiers: string[];
52
53
  allowedDomains: string;
53
54
  invalidDomainIdentifiers: string[];
@@ -62,15 +63,17 @@ export declare class UserRoles extends Component<UserRolesProps, UserRolesState>
62
63
  setStateFromProps: (props: UserRolesProps) => void;
63
64
  textForRole: (role: string) => string;
64
65
  singularArticleForRole: (role: string) => string;
65
- addUsers: (ids: string[], role: BASE_ROLE) => void;
66
+ addUserRoles: (ids: string[], role: string) => void;
66
67
  didAdd: (data?: FetchError | AddBusinessModel | undefined) => void;
67
- alertRemoveUser: (userToRemove: UserWithRoles, roleForRemove: string) => void;
68
- removeUserTitle: (roleForRemove: string) => string;
69
- renderRemoveUserDescription: (userToRemove: User, role: string, warning?: JSX.Element | undefined) => JSX.Element;
70
- removeUser: (shouldRemove: boolean) => void;
68
+ updateUserRole: (userToUpdate: UserRole, newRole: string) => void;
69
+ didUpdate: (isSuccess: boolean) => void;
70
+ alertRemoveUserRole: (userToRemove: UserRole) => void;
71
+ removeUserRoleTitle: (roleForRemove: string) => string;
72
+ renderRemoveUserRoleDescription: (userRoleToRemove: UserRole, warning?: JSX.Element | undefined) => JSX.Element;
73
+ removeUserRole: (shouldRemove: boolean) => void;
71
74
  didRemove: (isSuccess: boolean) => void;
72
75
  render(): JSX.Element;
73
76
  }
74
77
  export declare const mapStateToProps: (state: BaseReduxState, ownProps: UserRolesOwnProps) => UserRolesReduxProps;
75
- declare const _default: import("react-redux").ConnectedComponent<typeof UserRoles, Pick<React.ClassAttributes<UserRoles> & UserRolesProps, "externalProviders" | "model" | "ref" | "onChange" | "key" | "disabled" | "guid" | "load" | "modelName" | "pathParams" | "modelStatus" | "queryParams" | "disableAutoLoad" | "modelArray" | "stopPeriodicLoad" | "create" | "update" | "delete" | "previousModelStatus" | "fetchingId" | "textForRole" | "entityName" | "defaultRole" | "roleDescriptions" | "renderAddDescription" | "modifyUserRoleActivityName" | "filterUsers" | "addRoleBlacklist" | "renderTableDescription" | "entity" | "singularArticleForRole" | "isDeleteDisabled"> & UserRolesOwnProps>;
78
+ declare const _default: import("react-redux").ConnectedComponent<typeof UserRoles, Pick<React.ClassAttributes<UserRoles> & UserRolesProps, "externalProviders" | "model" | "ref" | "onChange" | "key" | "disabled" | "guid" | "load" | "modelName" | "pathParams" | "modelStatus" | "queryParams" | "disableAutoLoad" | "modelArray" | "stopPeriodicLoad" | "create" | "update" | "delete" | "previousModelStatus" | "fetchingId" | "textForRole" | "entityName" | "defaultRole" | "roleDescriptions" | "renderAddDescription" | "modifyUserRoleActivityName" | "filterUsers" | "addRoleBlacklist" | "renderTableDescription" | "entity" | "singularArticleForRole" | "isDeleteDisabled" | "allowMultipleRoles"> & UserRolesOwnProps>;
76
79
  export default _default;
@@ -41,6 +41,7 @@ var react_1 = __importStar(require("react"));
41
41
  var react_bootstrap_1 = require("react-bootstrap");
42
42
  var react_redux_1 = require("react-redux");
43
43
  var studiokit_net_js_1 = require("studiokit-net-js");
44
+ var fetchSaga_1 = require("studiokit-net-js/lib/fetchSaga");
44
45
  var uuid_1 = require("uuid");
45
46
  var AlertDialog_1 = __importDefault(require("../../components/AlertDialog"));
46
47
  var Loading_1 = __importDefault(require("../../components/Loading"));
@@ -55,6 +56,7 @@ var domainIdentifier_1 = require("../../utils/domainIdentifier");
55
56
  var entityUserRole_1 = require("../../utils/entityUserRole");
56
57
  var sort_1 = require("../../utils/sort");
57
58
  var user_1 = require("../../utils/user");
59
+ var userRole_1 = require("../../utils/userRole");
58
60
  var AlertWithIcon_1 = __importDefault(require("../AlertWithIcon"));
59
61
  /**
60
62
  * Component used to manage either UserRoles (global roles) or EntityUserRoles.
@@ -71,19 +73,33 @@ var UserRoles = /** @class */ (function (_super) {
71
73
  identifiersToAdd: undefined,
72
74
  roleForAdd: undefined,
73
75
  shouldResetAddForm: false,
76
+ // update
77
+ userRoleToUpdate: undefined,
74
78
  // remove
75
79
  shouldShowRemoveDialog: false,
76
- userToRemove: undefined,
77
- roleForRemove: undefined,
80
+ userRoleToRemove: undefined,
78
81
  // messages
79
82
  successMessage: undefined,
80
- existingUsersMessage: undefined,
83
+ existingMessage: undefined,
81
84
  failMessage: undefined
82
85
  };
83
86
  _this.setStateFromProps = function (props) {
84
87
  var userRoles = props.modelArray, filterUsers = props.filterUsers;
88
+ var usersWithRoles = Object.values(userRoles.reduce(function (result, userRole) {
89
+ var userId = userRole_1.getUserId(userRole);
90
+ var userWithRoles = result[userId];
91
+ if (!userWithRoles) {
92
+ userWithRoles = userRole_1.convertToUserWithRoles(userRole);
93
+ }
94
+ else {
95
+ userWithRoles.roles.push(userRole);
96
+ }
97
+ result[userId] = userWithRoles;
98
+ return result;
99
+ }, {}));
100
+ var sortedUsers = filterUsers(usersWithRoles).sort(sort_1.sortByNames);
85
101
  _this.setState({
86
- sortedUsers: filterUsers(userRoles).sort(sort_1.sortByNames)
102
+ sortedUsers: sortedUsers
87
103
  });
88
104
  };
89
105
  _this.textForRole = function (role) {
@@ -95,7 +111,7 @@ var UserRoles = /** @class */ (function (_super) {
95
111
  : baseRole_2.singularArticleForBaseRole(role);
96
112
  };
97
113
  //#region Add Users
98
- _this.addUsers = function (ids, role) {
114
+ _this.addUserRoles = function (ids, role) {
99
115
  var entity = _this.props.entity;
100
116
  _this.setState({
101
117
  identifiersToAdd: ids,
@@ -124,7 +140,7 @@ var UserRoles = /** @class */ (function (_super) {
124
140
  });
125
141
  };
126
142
  _this.didAdd = function (data) {
127
- var _a = _this.props, entityName = _a.entityName, load = _a.load, onChange = _a.onChange;
143
+ var _a = _this.props, entityName = _a.entityName, onChange = _a.onChange, model = _a.model, modelName = _a.modelName, pathParams = _a.pathParams;
128
144
  var _b = _this.state, roleForAdd = _b.roleForAdd, identifiersToAdd = _b.identifiersToAdd;
129
145
  if (!roleForAdd || !identifiersToAdd || identifiersToAdd.length === 0) {
130
146
  throw new Error('didAdd was called in the incorrect state');
@@ -141,29 +157,29 @@ var UserRoles = /** @class */ (function (_super) {
141
157
  });
142
158
  return;
143
159
  }
144
- var _c = data, addedUsers = _c.addedUsers, existingUsers = _c.existingUsers, invalidIdentifiers = _c.invalidIdentifiers, allowedDomains = _c.allowedDomains, invalidDomainIdentifiers = _c.invalidDomainIdentifiers;
160
+ var _c = data, addedUserRoles = _c.addedUserRoles, existingUserRoles = _c.existingUserRoles, invalidIdentifiers = _c.invalidIdentifiers, allowedDomains = _c.allowedDomains, invalidDomainIdentifiers = _c.invalidDomainIdentifiers;
145
161
  var roleString = _this.textForRole(roleForAdd).toLowerCase();
146
162
  var singularArticleString = _this.singularArticleForRole(roleForAdd);
147
- var addedNames = !!addedUsers && addedUsers.length > 0
148
- ? addedUsers
163
+ var addedNames = !!addedUserRoles && addedUserRoles.length > 0
164
+ ? addedUserRoles
149
165
  .map(function (au) {
150
166
  return "" + user_1.displayName(au) + (au.uid ? " (" + au.uid + ")" : '');
151
167
  })
152
168
  .join('\r\n')
153
169
  : undefined;
154
170
  var successMessage = addedNames
155
- ? "The following " + roleString + (addedUsers.length > 1 ? 's were' : ' was') + " successfully added" + (entityName ? " to your " + entityName : '') + ":\r\n" + addedNames
171
+ ? "The following " + roleString + (addedUserRoles.length > 1 ? 's were' : ' was') + " successfully added" + (entityName ? " to your " + entityName : '') + ":\r\n" + addedNames
156
172
  : undefined;
157
- var unchangedNames = !!existingUsers && existingUsers.length > 0
158
- ? existingUsers.map(function (eu) { return "" + user_1.displayName(eu) + (eu.uid ? " (" + eu.uid + ")" : ''); }).join('\r\n')
173
+ var existingNames = !!existingUserRoles && existingUserRoles.length > 0
174
+ ? existingUserRoles.map(function (eu) { return "" + user_1.displayName(eu) + (eu.uid ? " (" + eu.uid + ")" : ''); }).join('\r\n')
159
175
  : undefined;
160
- var hasMultipleExistingUsers = existingUsers.length > 1;
161
- var existingUsersMessage = unchangedNames
162
- ? "The following " + (hasMultipleExistingUsers ? 'people were' : 'person was') + " already " + (entityName
163
- ? "in your " + entityName + " as " + (hasMultipleExistingUsers ? '' : singularArticleString + " ")
164
- : hasMultipleExistingUsers
176
+ var hasMultipleExisting = existingUserRoles.length > 1;
177
+ var existingMessage = existingNames
178
+ ? "The following " + (hasMultipleExisting ? 'people were' : 'person was') + " already " + (entityName
179
+ ? "in your " + entityName + " as " + (hasMultipleExisting ? '' : singularArticleString + " ")
180
+ : hasMultipleExisting
165
181
  ? ''
166
- : singularArticleString + " ") + roleString + (hasMultipleExistingUsers ? 's' : '') + ":\r\n" + unchangedNames
182
+ : singularArticleString + " ") + roleString + (hasMultipleExisting ? 's' : '') + ":\r\n" + existingNames
167
183
  : undefined;
168
184
  var failMessage = !!invalidIdentifiers && invalidIdentifiers.length > 0
169
185
  ? "The following " + domainIdentifier_1.getDomainIdentifierTypePluralString() + " are invalid:\r\n" + invalidIdentifiers.join('\r\n')
@@ -177,46 +193,103 @@ var UserRoles = /** @class */ (function (_super) {
177
193
  identifiersToAdd: undefined,
178
194
  roleForAdd: undefined,
179
195
  successMessage: successMessage,
180
- existingUsersMessage: existingUsersMessage,
196
+ existingMessage: existingMessage,
181
197
  failMessage: failMessage
182
198
  });
183
199
  // only reload if we had some successful adds
184
200
  if (addedNames) {
185
- load();
201
+ // update redux with added userRoles
202
+ var updatedModel_1 = lodash_1.cloneDeep(model);
203
+ addedUserRoles.forEach(function (userRole) { return (updatedModel_1[userRole.id] = lodash_1.cloneDeep(userRole)); });
204
+ var prepareFetchResult = fetchSaga_1.prepareFetch({ type: studiokit_net_js_1.NET_ACTION.DATA_REQUESTED, modelName: modelName, pathParams: pathParams });
205
+ actionCreator_1.dispatchAction(studiokit_net_js_1.NET_ACTION.FETCH_RESULT_RECEIVED, {
206
+ modelName: prepareFetchResult.modelName,
207
+ data: updatedModel_1
208
+ });
186
209
  if (onChange) {
187
210
  onChange();
188
211
  }
189
212
  }
190
213
  };
191
214
  //#endregion Add Users
215
+ //#region Update
216
+ _this.updateUserRole = function (userToUpdate, newRole) {
217
+ _this.setState({
218
+ userRoleToUpdate: userToUpdate,
219
+ roleForUpdate: newRole,
220
+ successMessage: undefined,
221
+ failMessage: undefined
222
+ });
223
+ _this.props.update({
224
+ id: userToUpdate.id.toString(),
225
+ body: undefined,
226
+ queryParams: {
227
+ roleName: newRole
228
+ }
229
+ });
230
+ };
231
+ _this.didUpdate = function (isSuccess) {
232
+ var _a = _this.props, entityName = _a.entityName, onChange = _a.onChange;
233
+ var _b = _this.state, userToUpdate = _b.userRoleToUpdate, roleForUpdate = _b.roleForUpdate;
234
+ if (userToUpdate === undefined) {
235
+ throw new Error('`didUpdate` was called without `userToUpdate` in state');
236
+ }
237
+ if (roleForUpdate === undefined) {
238
+ throw new Error('`didUpdate` was called without `roleForUpdate` in state');
239
+ }
240
+ var name = user_1.displayName(userToUpdate);
241
+ var roleString = _this.textForRole(roleForUpdate).toLowerCase();
242
+ var singularArticleString = _this.singularArticleForRole(roleForUpdate);
243
+ if (!isSuccess) {
244
+ var failMessage = "Oops! There was an error updating " + name + " to " + singularArticleString + " " + roleString + (entityName ? " in your " + entityName : '') + ". Please try again.";
245
+ _this.setState({
246
+ userRoleToUpdate: undefined,
247
+ roleForUpdate: undefined,
248
+ failMessage: failMessage
249
+ });
250
+ return;
251
+ }
252
+ var successMessage = name + " was successfully updated to " + singularArticleString + " " + roleString + (entityName ? " in your " + entityName : '') + ".";
253
+ _this.setState({
254
+ userRoleToUpdate: undefined,
255
+ roleForUpdate: undefined,
256
+ successMessage: successMessage
257
+ });
258
+ if (onChange) {
259
+ onChange();
260
+ }
261
+ };
262
+ //#endregion Update
192
263
  //#region Remove User
193
- _this.alertRemoveUser = function (userToRemove, roleForRemove) {
264
+ _this.alertRemoveUserRole = function (userToRemove) {
194
265
  _this.setState({
195
- userToRemove: userToRemove,
196
- shouldShowRemoveDialog: true,
197
- roleForRemove: roleForRemove
266
+ userRoleToRemove: userToRemove,
267
+ shouldShowRemoveDialog: true
198
268
  });
199
269
  };
200
- _this.removeUserTitle = function (roleForRemove) {
270
+ _this.removeUserRoleTitle = function (roleForRemove) {
201
271
  return "Remove " + _this.textForRole(roleForRemove);
202
272
  };
203
- _this.renderRemoveUserDescription = function (userToRemove, role, warning) {
273
+ _this.renderRemoveUserRoleDescription = function (userRoleToRemove, warning) {
204
274
  var _a = _this.props, entity = _a.entity, externalProviders = _a.externalProviders;
205
275
  var group = entity && entity.externalGroups ? entity : undefined;
206
- var roleString = _this.textForRole(role).toLowerCase();
207
- var singularArticleString = _this.singularArticleForRole(role);
276
+ var roleString = _this.textForRole(userRoleToRemove.role).toLowerCase();
277
+ var singularArticleString = _this.singularArticleForRole(userRoleToRemove.role);
208
278
  var defaultWarning = warning !== null && warning !== void 0 ? warning : (react_1.default.createElement("p", { className: "ma0" },
209
279
  "Are you sure you want to ",
210
280
  react_1.default.createElement("strong", null,
211
281
  "remove ",
212
- user_1.displayName(userToRemove)),
213
- " as ",
214
- singularArticleString,
282
+ user_1.displayName(userRoleToRemove)),
283
+ " as",
215
284
  ' ',
285
+ singularArticleString,
286
+ " ",
216
287
  roleString,
217
288
  "?"));
218
- var externalGroupsToRemove = group === null || group === void 0 ? void 0 : group.externalGroups.filter(function (eg) { return eg.userId === userToRemove.id; });
219
- if (!externalGroupsToRemove || externalGroupsToRemove.length === 0 || role !== baseRole_1.default.GROUP_OWNER) {
289
+ var externalGroupsToRemove = group === null || group === void 0 ? void 0 : group.externalGroups.filter(function (eg) { return eg.userId === userRoleToRemove.id; });
290
+ if (!externalGroupsToRemove ||
291
+ externalGroupsToRemove.length === 0 ||
292
+ userRoleToRemove.role !== baseRole_1.default.GROUP_OWNER) {
220
293
  return defaultWarning;
221
294
  }
222
295
  var externalGroupsToRemoveWithRosterSync = externalGroupsToRemove.filter(function (eg) { var _a; return (_a = externalProviders === null || externalProviders === void 0 ? void 0 : externalProviders[eg.externalProviderId]) === null || _a === void 0 ? void 0 : _a.rosterSyncEnabled; });
@@ -233,51 +306,45 @@ var UserRoles = /** @class */ (function (_super) {
233
306
  react_1.default.createElement("ul", null, externalGroupsToRemove.map(function (eg) { return (react_1.default.createElement("li", { key: eg.id }, eg.description)); })),
234
307
  defaultWarning));
235
308
  };
236
- _this.removeUser = function (shouldRemove) {
237
- var entity = _this.props.entity;
238
- var _a = _this.state, userToRemove = _a.userToRemove, roleForRemove = _a.roleForRemove;
239
- if (userToRemove === undefined) {
240
- throw new Error('removeUser was called without setting userToRemove in state');
241
- }
242
- if (roleForRemove === undefined) {
243
- throw new Error('removeUser was called without setting rollForRemove in state');
309
+ _this.removeUserRole = function (shouldRemove) {
310
+ var userRoleToRemove = _this.state.userRoleToRemove;
311
+ if (userRoleToRemove === undefined) {
312
+ throw new Error('`removeUser` was called without setting `userRoleToRemove` in state');
244
313
  }
245
314
  _this.setState({
246
315
  shouldShowRemoveDialog: false,
247
316
  successMessage: undefined,
248
317
  failMessage: undefined,
249
318
  // clear if cancelled
250
- userToRemove: shouldRemove ? userToRemove : undefined
319
+ userRoleToRemove: shouldRemove ? userRoleToRemove : undefined
251
320
  });
252
321
  if (!shouldRemove) {
253
322
  return;
254
323
  }
255
324
  _this.props.delete({
256
- id: userToRemove.id,
257
- body: entity ? { roleName: roleForRemove, entityId: entity.id } : undefined
325
+ id: userRoleToRemove.id
258
326
  });
259
327
  };
260
328
  _this.didRemove = function (isSuccess) {
261
- var _a = _this.props, entityName = _a.entityName, load = _a.load, onChange = _a.onChange;
262
- var userToRemove = _this.state.userToRemove;
263
- if (userToRemove === undefined) {
264
- throw new Error('didRemove was called without setting state correctly');
329
+ var _a = _this.props, entityName = _a.entityName, onChange = _a.onChange;
330
+ var userRoleToRemove = _this.state.userRoleToRemove;
331
+ if (userRoleToRemove === undefined) {
332
+ throw new Error('`didRemove` was called without setting `userRoleToRemove` in state');
265
333
  }
266
- var name = user_1.displayName(userToRemove);
334
+ var name = user_1.displayName(userRoleToRemove);
267
335
  if (!isSuccess) {
268
336
  var failMessage = "Oops! There was an error removing " + name + (entityName ? " from your " + entityName : '') + ". Please try again.";
269
337
  _this.setState({
270
- userToRemove: undefined,
338
+ userRoleToRemove: undefined,
271
339
  failMessage: failMessage
272
340
  });
273
341
  return;
274
342
  }
275
343
  var successMessage = name + " was successfully removed" + (entityName ? " from your " + entityName : '') + ".";
276
344
  _this.setState({
277
- userToRemove: undefined,
345
+ userRoleToRemove: undefined,
278
346
  successMessage: successMessage
279
347
  });
280
- load();
281
348
  if (onChange) {
282
349
  onChange();
283
350
  }
@@ -302,6 +369,10 @@ var UserRoles = /** @class */ (function (_super) {
302
369
  failMessage: "Oops! There was an error loading" + (entityName ? " the people for your " + entityName : '') + ".\r\nPlease try again."
303
370
  });
304
371
  }
372
+ // updating
373
+ if (prevModelStatus === modelStatus_1.default.UPDATING && modelStatus !== modelStatus_1.default.UPDATING) {
374
+ this.didUpdate(modelStatus === modelStatus_1.default.READY);
375
+ }
305
376
  // removing
306
377
  if (prevModelStatus === modelStatus_1.default.DELETING && modelStatus !== modelStatus_1.default.DELETING) {
307
378
  this.didRemove(modelStatus === modelStatus_1.default.READY);
@@ -311,7 +382,7 @@ var UserRoles = /** @class */ (function (_super) {
311
382
  UserRoles.prototype.render = function () {
312
383
  var _this = this;
313
384
  var _a = this.props, modelStatus = _a.modelStatus, canModify = _a.canModify, canModifySelf = _a.canModifySelf, entityName = _a.entityName, renderTableDescription = _a.renderTableDescription, defaultRole = _a.defaultRole, roleDescriptions = _a.roleDescriptions, renderAddDescription = _a.renderAddDescription, disabled = _a.disabled, isDeleteDisabled = _a.isDeleteDisabled, addRoleBlacklist = _a.addRoleBlacklist;
314
- var _b = this.state, isAddingUsers = _b.isAddingUsers, sortedUsers = _b.sortedUsers, shouldResetAddForm = _b.shouldResetAddForm, shouldShowRemoveDialog = _b.shouldShowRemoveDialog, userToRemove = _b.userToRemove, roleForRemove = _b.roleForRemove, successMessage = _b.successMessage, existingUsersMessage = _b.existingUsersMessage, failMessage = _b.failMessage;
385
+ var _b = this.state, isAddingUsers = _b.isAddingUsers, sortedUsers = _b.sortedUsers, shouldResetAddForm = _b.shouldResetAddForm, shouldShowRemoveDialog = _b.shouldShowRemoveDialog, userRoleToRemove = _b.userRoleToRemove, successMessage = _b.successMessage, existingMessage = _b.existingMessage, failMessage = _b.failMessage;
315
386
  var addableRoleDescriptions = addRoleBlacklist
316
387
  ? lodash_1.pickBy(roleDescriptions, function (_, key) { return !addRoleBlacklist.includes(key); })
317
388
  : roleDescriptions;
@@ -323,25 +394,25 @@ var UserRoles = /** @class */ (function (_super) {
323
394
  });
324
395
  } },
325
396
  react_1.default.createElement("p", { className: "pre-wrap" }, successMessage))),
326
- !!existingUsersMessage && (react_1.default.createElement(AlertWithIcon_1.default, { id: "existingUsersMessageAlert", variant: "info", dismissible: true, onClose: function () {
397
+ !!existingMessage && (react_1.default.createElement(AlertWithIcon_1.default, { id: "existingMessageAlert", variant: "info", dismissible: true, onClose: function () {
327
398
  return _this.setState({
328
- existingUsersMessage: undefined
399
+ existingMessage: undefined
329
400
  });
330
401
  } },
331
- react_1.default.createElement("p", { className: "pre-wrap" }, existingUsersMessage))),
402
+ react_1.default.createElement("p", { className: "pre-wrap" }, existingMessage))),
332
403
  !!failMessage && (react_1.default.createElement(AlertWithIcon_1.default, { id: "failMessageAlert", variant: "warning", dismissible: true, onClose: function () {
333
404
  return _this.setState({
334
405
  failMessage: undefined
335
406
  });
336
407
  } },
337
408
  react_1.default.createElement("p", { className: "pre-wrap" }, failMessage))),
338
- canModify && (react_1.default.createElement(Add_1.default, { id: "entityUserRolesAdd", entityName: entityName, addUsersToRole: this.addUsers, shouldReset: shouldResetAddForm, isAddingUsersToRole: isAddingUsers, defaultRole: defaultRole, roleDescriptions: addableRoleDescriptions, renderAddDescription: renderAddDescription, disabled: disabled, textForRole: this.textForRole })),
409
+ canModify && (react_1.default.createElement(Add_1.default, { id: "entityUserRolesAdd", entityName: entityName, addUsersToRole: this.addUserRoles, shouldReset: shouldResetAddForm, isAddingUsersToRole: isAddingUsers, defaultRole: defaultRole, roleDescriptions: addableRoleDescriptions, renderAddDescription: renderAddDescription, disabled: disabled, textForRole: this.textForRole })),
339
410
  !!renderTableDescription && renderTableDescription(canModify),
340
411
  react_1.default.createElement(react_bootstrap_1.Row, { className: "mt3" },
341
412
  react_1.default.createElement(react_bootstrap_1.Col, { xs: 12 }, modelStatus === modelStatus_1.default.LOADING ? (react_1.default.createElement(Loading_1.default, null)) : sortedUsers.length > 0 ? (react_1.default.createElement(Table_1.UserRolesTable, { id: "entityUserRolesTable", users: sortedUsers, readOnly: !canModify || isDeleteDisabled, roles: roles,
342
413
  // Assumes the default is the groupOwner, assignment/assessmentOwner, rubricOwner, problemOwner etc.
343
- entityOwnerRole: defaultRole, canModifySelf: canModifySelf, removeUserFromRole: this.alertRemoveUser, textForRole: this.textForRole })) : null)),
344
- !!userToRemove && !!roleForRemove && (react_1.default.createElement(AlertDialog_1.default, { id: "removeUserAlert", isOpen: shouldShowRemoveDialog, title: this.removeUserTitle(roleForRemove), description: this.renderRemoveUserDescription(userToRemove, roleForRemove), onDestroy: function () { return _this.removeUser(true); }, destroyText: "Yes, remove the user", onCancel: function () { return _this.removeUser(false); }, cancelText: "No, I changed my mind" }))));
414
+ entityOwnerRole: defaultRole, canModifySelf: canModifySelf, removeUserRole: this.alertRemoveUserRole, textForRole: this.textForRole })) : null)),
415
+ !!userRoleToRemove && (react_1.default.createElement(AlertDialog_1.default, { id: "removeUserAlert", isOpen: shouldShowRemoveDialog, title: this.removeUserRoleTitle(userRoleToRemove.role), description: this.renderRemoveUserRoleDescription(userRoleToRemove), onDestroy: function () { return _this.removeUserRole(true); }, destroyText: "Yes, remove the user", onCancel: function () { return _this.removeUserRole(false); }, cancelText: "No, I changed my mind" }))));
345
416
  };
346
417
  return UserRoles;
347
418
  }(react_1.Component));
@@ -1,5 +1,5 @@
1
1
  import { ModelCollection } from 'studiokit-net-js';
2
- import { AppConfiguration, ExternalProvider, ExternalTerm, Group, GroupUserWithRoles, SimpleLocation, UserInfo, UserWithRoles } from '../types';
2
+ import { AppConfiguration, ExternalProvider, ExternalTerm, Group, GroupUserRole, SimpleLocation, UserInfo, UserRole } from '../types';
3
3
  export declare const defaultAppConfiguration: AppConfiguration;
4
4
  export declare const defaultLocation: SimpleLocation;
5
5
  export declare function mockHistory(): History;
@@ -31,7 +31,6 @@ export declare const defaultNamelessUserInfo: {
31
31
  activities: string[];
32
32
  dateDemoGenerationSucceeded: string | null;
33
33
  dateStored: string;
34
- /** 5/15/18 - 8/14/18 */
35
34
  dateLastUpdated: string;
36
35
  isImpersonated: boolean;
37
36
  id: string;
@@ -52,7 +51,6 @@ export declare const defaultNamedUserInfo: {
52
51
  activities: string[];
53
52
  dateDemoGenerationSucceeded: string | null;
54
53
  dateStored: string;
55
- /** 5/15/18 - 8/14/18 */
56
54
  dateLastUpdated: string;
57
55
  isImpersonated: boolean;
58
56
  id: string;
@@ -64,14 +62,14 @@ export declare function mockUser(activities?: string[]): {
64
62
  userInfo: UserInfo;
65
63
  };
66
64
  export declare const defaultGroupOwnerUserInfo: UserInfo;
67
- export declare const defaultGroupOwner: GroupUserWithRoles;
68
- export declare const defaultNamelessGroupLearner: GroupUserWithRoles;
69
- export declare const defaultNamedGroupLearner: GroupUserWithRoles;
70
- export declare const defaultGroupLearner: GroupUserWithRoles;
71
- export declare const defaultExternalGroupLearner: GroupUserWithRoles;
72
- export declare const defaultGroupGrader: GroupUserWithRoles;
73
- export declare const defaultGroupUsers: GroupUserWithRoles[];
74
- export declare const defaultAdmins: UserWithRoles[];
65
+ export declare const defaultGroupOwner: GroupUserRole;
66
+ export declare const defaultNamelessGroupLearner: GroupUserRole;
67
+ export declare const defaultNamedGroupLearner: GroupUserRole;
68
+ export declare const defaultGroupLearner: GroupUserRole;
69
+ export declare const defaultExternalGroupLearner: GroupUserRole;
70
+ export declare const defaultGroupGrader: GroupUserRole;
71
+ export declare const defaultGroupUserRoles: GroupUserRole[];
72
+ export declare const defaultAdminUserRoles: UserRole[];
75
73
  export declare const defaultGroup: Group;
76
74
  export declare function mockGroups(activities?: string[], roles?: string[]): ModelCollection<Group>;
77
75
  export declare function mockSyncedGroups(activities?: string[], roles?: string[]): ModelCollection<Group>;
@@ -14,8 +14,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.defaultExternalTerms = exports.defaultExternalProviders = exports.mockPastAndCurrentGroups = exports.mockPastGroups = exports.mockTermAndUniTimeGroups = exports.mockTermGroups = exports.mockLtiGroups = exports.mockSyncedGroups = exports.mockGroups = exports.defaultGroup = exports.defaultAdmins = exports.defaultGroupUsers = exports.defaultGroupGrader = exports.defaultExternalGroupLearner = exports.defaultGroupLearner = exports.defaultNamedGroupLearner = exports.defaultNamelessGroupLearner = exports.defaultGroupOwner = exports.defaultGroupOwnerUserInfo = exports.mockUser = exports.defaultNamedUserInfo = exports.defaultNamelessUserInfo = exports.defaultUser = exports.defaultDate = exports.currentDates = exports.pastDates = exports.mockHistory = exports.defaultLocation = exports.defaultAppConfiguration = void 0;
18
- var lodash_1 = __importDefault(require("lodash"));
17
+ exports.defaultExternalTerms = exports.defaultExternalProviders = exports.mockPastAndCurrentGroups = exports.mockPastGroups = exports.mockTermAndUniTimeGroups = exports.mockTermGroups = exports.mockLtiGroups = exports.mockSyncedGroups = exports.mockGroups = exports.defaultGroup = exports.defaultAdminUserRoles = exports.defaultGroupUserRoles = exports.defaultGroupGrader = exports.defaultExternalGroupLearner = exports.defaultGroupLearner = exports.defaultNamedGroupLearner = exports.defaultNamelessGroupLearner = exports.defaultGroupOwner = exports.defaultGroupOwnerUserInfo = exports.mockUser = exports.defaultNamedUserInfo = exports.defaultNamelessUserInfo = exports.defaultUser = exports.defaultDate = exports.currentDates = exports.pastDates = exports.mockHistory = exports.defaultLocation = exports.defaultAppConfiguration = void 0;
18
+ var lodash_1 = require("lodash");
19
19
  var externalProviderType_1 = __importDefault(require("../constants/externalProviderType"));
20
20
  var baseRole_1 = __importDefault(require("./baseRole"));
21
21
  var tier_1 = __importDefault(require("./tier"));
@@ -103,120 +103,85 @@ exports.defaultNamedUserInfo = __assign(__assign({}, exports.defaultUser.userInf
103
103
  });
104
104
  function mockUser(activities) {
105
105
  if (activities === void 0) { activities = []; }
106
- return lodash_1.default.merge({ userInfo: { activities: activities } }, exports.defaultUser);
106
+ return lodash_1.merge({ userInfo: { activities: activities } }, exports.defaultUser);
107
107
  }
108
108
  exports.mockUser = mockUser;
109
109
  exports.defaultGroupOwnerUserInfo = __assign(__assign({}, exports.defaultUser.userInfo), { id: '2', firstName: 'Jane', lastName: 'Doe', email: 'jane@gmail.com' });
110
110
  exports.defaultGroupOwner = {
111
- id: '2',
111
+ id: '1',
112
+ userId: '2',
112
113
  firstName: 'Jane',
113
114
  lastName: 'Doe',
114
115
  email: 'jane@gmail.com',
115
116
  uid: 'jane',
116
117
  entityId: 1,
117
- roles: [
118
- {
119
- userId: '2',
120
- entityId: 1,
121
- role: baseRole_1.default.GROUP_OWNER,
122
- isExternal: false
123
- }
124
- ]
118
+ role: baseRole_1.default.GROUP_OWNER,
119
+ isExternal: false
125
120
  };
126
121
  exports.defaultNamelessGroupLearner = {
127
- id: '3',
122
+ id: '2',
123
+ userId: '3',
128
124
  firstName: null,
129
125
  lastName: null,
130
126
  email: 'nicki@minaj.superbass',
131
127
  uid: 'nm-nameless',
132
128
  entityId: 1,
133
- roles: [
134
- {
135
- userId: '3',
136
- entityId: 1,
137
- role: baseRole_1.default.GROUP_LEARNER,
138
- isExternal: false
139
- }
140
- ]
129
+ role: baseRole_1.default.GROUP_LEARNER,
130
+ isExternal: false
141
131
  };
142
132
  exports.defaultNamedGroupLearner = {
143
- id: '4',
133
+ id: '3',
134
+ userId: '4',
144
135
  firstName: 'Nicki',
145
136
  lastName: 'Minaj',
146
137
  email: null,
147
138
  uid: 'nm-named',
148
139
  entityId: 1,
149
- roles: [
150
- {
151
- userId: '4',
152
- entityId: 1,
153
- role: baseRole_1.default.GROUP_LEARNER,
154
- isExternal: false
155
- }
156
- ]
140
+ role: baseRole_1.default.GROUP_LEARNER,
141
+ isExternal: false
157
142
  };
158
143
  exports.defaultGroupLearner = {
159
- id: '3',
144
+ id: '4',
145
+ userId: '5',
160
146
  firstName: 'Joe',
161
147
  lastName: 'Schmoe',
162
148
  email: 'nope@gmail.com',
163
149
  uid: 'nope',
164
150
  entityId: 1,
165
- roles: [
166
- {
167
- userId: '3',
168
- entityId: 1,
169
- role: baseRole_1.default.GROUP_LEARNER,
170
- isExternal: false
171
- }
172
- ]
151
+ role: baseRole_1.default.GROUP_LEARNER,
152
+ isExternal: false
173
153
  };
174
154
  exports.defaultExternalGroupLearner = {
175
- id: '4',
155
+ id: '5',
156
+ userId: '6',
176
157
  firstName: 'Bob',
177
158
  lastName: 'Loblaw',
178
159
  email: 'bobloblaw@lawblog.com',
179
160
  uid: 'bobloblaw',
180
161
  entityId: 1,
181
- roles: [
182
- {
183
- userId: '4',
184
- entityId: 1,
185
- role: baseRole_1.default.GROUP_LEARNER,
186
- isExternal: true
187
- }
188
- ]
162
+ role: baseRole_1.default.GROUP_LEARNER,
163
+ isExternal: true
189
164
  };
190
165
  exports.defaultGroupGrader = {
191
- id: '5',
166
+ id: '6',
167
+ userId: '7',
192
168
  firstName: 'Grader',
193
169
  lastName: 'McGradeface',
194
170
  email: 'grader@gmail.com',
195
171
  uid: 'grader',
196
172
  entityId: 1,
197
- roles: [
198
- {
199
- userId: '35',
200
- entityId: 1,
201
- role: baseRole_1.default.GROUP_GRADER,
202
- isExternal: false
203
- }
204
- ]
173
+ role: baseRole_1.default.GROUP_GRADER,
174
+ isExternal: false
205
175
  };
206
- exports.defaultGroupUsers = [exports.defaultGroupOwner, exports.defaultGroupLearner, exports.defaultExternalGroupLearner];
207
- exports.defaultAdmins = [
176
+ exports.defaultGroupUserRoles = [exports.defaultGroupOwner, exports.defaultGroupLearner, exports.defaultExternalGroupLearner];
177
+ exports.defaultAdminUserRoles = [
208
178
  {
209
179
  id: '1',
210
180
  firstName: 'Joe',
211
181
  lastName: 'Schmo',
212
182
  email: null,
213
183
  uid: null,
214
- roles: [
215
- {
216
- userId: '1',
217
- role: baseRole_1.default.ADMIN
218
- }
219
- ]
184
+ role: baseRole_1.default.ADMIN
220
185
  },
221
186
  {
222
187
  id: '2',
@@ -224,12 +189,7 @@ exports.defaultAdmins = [
224
189
  lastName: null,
225
190
  email: 'carlysimon@clouds.in.coffee',
226
191
  uid: 'carlysimon',
227
- roles: [
228
- {
229
- userId: '2',
230
- role: baseRole_1.default.ADMIN
231
- }
232
- ]
192
+ role: baseRole_1.default.ADMIN
233
193
  }
234
194
  ];
235
195
  //#endregion Users
@@ -260,13 +220,13 @@ exports.defaultGroup = {
260
220
  function mockGroups(activities, roles) {
261
221
  if (activities === void 0) { activities = []; }
262
222
  if (roles === void 0) { roles = []; }
263
- return { '1': lodash_1.default.merge({ activities: activities, roles: roles }, exports.defaultGroup) };
223
+ return { '1': lodash_1.merge({ activities: activities, roles: roles }, exports.defaultGroup) };
264
224
  }
265
225
  exports.mockGroups = mockGroups;
266
226
  function mockSyncedGroups(activities, roles) {
267
227
  if (activities === void 0) { activities = []; }
268
228
  if (roles === void 0) { roles = []; }
269
- var rosterSyncEnabledGroup = lodash_1.default.merge({ activities: activities, roles: roles }, exports.defaultGroup);
229
+ var rosterSyncEnabledGroup = lodash_1.merge({ activities: activities, roles: roles }, exports.defaultGroup);
270
230
  rosterSyncEnabledGroup.isRosterSyncEnabled = true;
271
231
  return { '1': rosterSyncEnabledGroup };
272
232
  }
@@ -274,7 +234,7 @@ exports.mockSyncedGroups = mockSyncedGroups;
274
234
  function mockLtiGroups(activities, roles) {
275
235
  if (activities === void 0) { activities = []; }
276
236
  if (roles === void 0) { roles = []; }
277
- var ltiGroup = lodash_1.default.merge({ activities: activities, roles: roles }, exports.defaultGroup);
237
+ var ltiGroup = lodash_1.merge({ activities: activities, roles: roles }, exports.defaultGroup);
278
238
  ltiGroup.isRosterSyncEnabled = true;
279
239
  ltiGroup.externalGroups = [
280
240
  {
@@ -297,7 +257,7 @@ exports.mockLtiGroups = mockLtiGroups;
297
257
  function mockTermGroups(activities, roles) {
298
258
  if (activities === void 0) { activities = []; }
299
259
  if (roles === void 0) { roles = []; }
300
- var group = lodash_1.default.merge({ activities: activities, roles: roles }, exports.defaultGroup);
260
+ var group = lodash_1.merge({ activities: activities, roles: roles }, exports.defaultGroup);
301
261
  group.startDate = null;
302
262
  group.endDate = null;
303
263
  group.externalTermId = 1;
@@ -307,7 +267,7 @@ exports.mockTermGroups = mockTermGroups;
307
267
  function mockTermAndUniTimeGroups(activities, roles) {
308
268
  if (activities === void 0) { activities = []; }
309
269
  if (roles === void 0) { roles = []; }
310
- var group = lodash_1.default.merge({ activities: activities, roles: roles }, exports.defaultGroup);
270
+ var group = lodash_1.merge({ activities: activities, roles: roles }, exports.defaultGroup);
311
271
  group.startDate = null;
312
272
  group.endDate = null;
313
273
  group.externalTermId = 1;
@@ -332,15 +292,15 @@ exports.mockTermAndUniTimeGroups = mockTermAndUniTimeGroups;
332
292
  function mockPastGroups(activities, roles) {
333
293
  if (activities === void 0) { activities = []; }
334
294
  if (roles === void 0) { roles = []; }
335
- var pastGroup = lodash_1.default.merge({ activities: activities, roles: roles }, exports.defaultGroup, exports.pastDates);
295
+ var pastGroup = lodash_1.merge({ activities: activities, roles: roles }, exports.defaultGroup, exports.pastDates);
336
296
  return { '1': pastGroup };
337
297
  }
338
298
  exports.mockPastGroups = mockPastGroups;
339
299
  function mockPastAndCurrentGroups(activities, roles) {
340
300
  if (activities === void 0) { activities = []; }
341
301
  if (roles === void 0) { roles = []; }
342
- var pastGroup = lodash_1.default.merge({ activities: activities, roles: roles }, exports.defaultGroup, exports.pastDates);
343
- var currentGroup = lodash_1.default.merge({ activities: activities, roles: roles }, exports.defaultGroup, {
302
+ var pastGroup = lodash_1.merge({ activities: activities, roles: roles }, exports.defaultGroup, exports.pastDates);
303
+ var currentGroup = lodash_1.merge({ activities: activities, roles: roles }, exports.defaultGroup, {
344
304
  id: '2'
345
305
  }, exports.currentDates);
346
306
  return { '1': pastGroup, '2': currentGroup };
@@ -1,4 +1,4 @@
1
1
  import { EndpointMapping, EndpointMappings } from 'studiokit-net-js';
2
- export declare const entityUserRoleEndpointMappings: (typename: string) => EndpointMappings;
2
+ export declare const entityUserRoleEndpointMappings: (endpointName: string) => EndpointMappings;
3
3
  export declare const groupEndpointMapping: EndpointMapping;
4
4
  export declare const endpointMappings: EndpointMappings;
@@ -12,37 +12,27 @@ var __assign = (this && this.__assign) || function () {
12
12
  };
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
14
  exports.endpointMappings = exports.groupEndpointMapping = exports.entityUserRoleEndpointMappings = void 0;
15
- var entityUserRoleEndpointMappings = function (typename) {
16
- return {
17
- entityUserRoles: {
15
+ var entityUserRoleEndpointMappings = function (endpointName) {
16
+ var _a;
17
+ return _a = {},
18
+ _a[endpointName] = {
18
19
  _config: {
19
20
  isCollection: true,
20
21
  fetch: {
21
- path: '/api/entityUserRoles',
22
- // for GET
23
- queryParams: {
24
- typename: typename
25
- },
26
- // for DELETE
27
- body: {
28
- typename: typename
29
- }
22
+ path: "/api/" + endpointName
30
23
  }
31
24
  }
32
25
  },
33
26
  // use separate model for transient POSTs
34
- addUserRoles: {
27
+ _a.addUserRoles = {
35
28
  _config: {
36
29
  fetch: {
37
- path: '/api/entityUserRoles',
38
- method: 'POST',
39
- body: {
40
- typename: typename
41
- }
30
+ path: "/api/" + endpointName,
31
+ method: 'POST'
42
32
  }
43
33
  }
44
- }
45
- };
34
+ },
35
+ _a;
46
36
  };
47
37
  exports.entityUserRoleEndpointMappings = entityUserRoleEndpointMappings;
48
38
  exports.groupEndpointMapping = __assign({ _config: {
@@ -56,7 +46,7 @@ exports.groupEndpointMapping = __assign({ _config: {
56
46
  method: 'POST'
57
47
  }
58
48
  }
59
- } }, exports.entityUserRoleEndpointMappings('Group'));
49
+ } }, exports.entityUserRoleEndpointMappings('groupUserRoles'));
60
50
  exports.endpointMappings = {
61
51
  urlChecker: {
62
52
  _config: {
@@ -1,7 +1,7 @@
1
1
  import { Model, ModelCollection } from 'studiokit-net-js';
2
2
  import { ExternalGroup } from './External';
3
3
  import { EntityUser } from './User';
4
- import { GroupUserWithRoles } from './UserRole';
4
+ import { GroupUserRole } from './UserRole';
5
5
  export interface Group extends Model {
6
6
  id: number;
7
7
  name: string;
@@ -15,5 +15,5 @@ export interface Group extends Model {
15
15
  owners: EntityUser[];
16
16
  graders: EntityUser[];
17
17
  externalGroups: ExternalGroup[];
18
- entityUserRoles?: ModelCollection<GroupUserWithRoles>;
18
+ groupUserRoles?: ModelCollection<GroupUserRole>;
19
19
  }
@@ -1,9 +1,9 @@
1
1
  import { User } from './User';
2
- export interface UserRole {
3
- userId: string;
2
+ export interface UserRole extends User {
4
3
  role: string;
5
4
  }
6
5
  export interface EntityUserRole extends UserRole {
6
+ userId: string;
7
7
  entityId: number;
8
8
  }
9
9
  export interface GroupUserRole extends EntityUserRole {
@@ -12,8 +12,3 @@ export interface GroupUserRole extends EntityUserRole {
12
12
  export interface UserWithRoles<TUserRole extends UserRole = UserRole> extends User {
13
13
  roles: TUserRole[];
14
14
  }
15
- export interface EntityUserWithRoles<TUserRole extends EntityUserRole = EntityUserRole> extends UserWithRoles<TUserRole> {
16
- entityId: number;
17
- }
18
- export interface GroupUserWithRoles extends EntityUserWithRoles<GroupUserRole> {
19
- }
@@ -1,7 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getRootModelName = void 0;
4
- var getRootModelName = function (props) {
5
- return props.modelName.replace('.entityUserRoles', '').replace('userRoles', '');
6
- };
4
+ var getRootModelName = function (props) { return props.modelName.split('.').slice(0, -1).join('.'); };
7
5
  exports.getRootModelName = getRootModelName;
@@ -1,8 +1,8 @@
1
1
  import { ModelCollection } from 'studiokit-net-js';
2
- import { Group, GroupUserWithRoles } from '../types';
2
+ import { Group, UserWithRoles } from '../types';
3
3
  export declare const groupsAsLearner: (groups: ModelCollection<Group>) => Group[];
4
4
  export declare const groupsAsOwner: (groups: ModelCollection<Group>) => Group[];
5
5
  export declare const groupsAsGrader: (groups: ModelCollection<Group>) => Group[];
6
6
  export declare const groupsAsAnythingButLearner: (groups: ModelCollection<Group>) => Group[];
7
- export declare const filterManualGroupUsers: (groupUsers: GroupUserWithRoles[]) => GroupUserWithRoles[];
8
- export declare const filterSyncedGroupUsers: (groupUsers: GroupUserWithRoles[]) => GroupUserWithRoles[];
7
+ export declare const filterManualGroupUsers: (groupUsers: UserWithRoles[]) => UserWithRoles<import("../types").UserRole>[];
8
+ export declare const filterSyncedGroupUsers: (groupUsers: UserWithRoles[]) => UserWithRoles<import("../types").UserRole>[];
@@ -7,6 +7,7 @@ exports.filterSyncedGroupUsers = exports.filterManualGroupUsers = exports.groups
7
7
  var lodash_1 = __importDefault(require("lodash"));
8
8
  var baseRole_1 = __importDefault(require("../constants/baseRole"));
9
9
  var model_1 = require("./model");
10
+ var userRole_1 = require("./userRole");
10
11
  var groupsAsLearner = function (groups) {
11
12
  return filterGroupsByRole(groups, baseRole_1.default.GROUP_LEARNER);
12
13
  };
@@ -33,10 +34,10 @@ var filterGroupsByRoleOtherThanRole = function (groups, role) {
33
34
  return lodash_1.default.values(lodash_1.default.omitBy(model_1.getModelArray(groups), function (value, key) { return !groupHasRole(value, key) || lodash_1.default.every(value.roles, function (r) { return r === role; }); }));
34
35
  };
35
36
  var filterManualGroupUsers = function (groupUsers) {
36
- return groupUsers.filter(function (groupUser) { return !groupUser.roles.some(function (r) { return r.isExternal; }); });
37
+ return groupUsers.filter(function (groupUser) { return !groupUser.roles.some(function (r) { return userRole_1.isExternal(r); }); });
37
38
  };
38
39
  exports.filterManualGroupUsers = filterManualGroupUsers;
39
40
  var filterSyncedGroupUsers = function (groupUsers) {
40
- return groupUsers.filter(function (groupUser) { return groupUser.roles.some(function (r) { return r.isExternal; }); });
41
+ return groupUsers.filter(function (groupUser) { return groupUser.roles.some(function (r) { return userRole_1.isExternal(r); }); });
41
42
  };
42
43
  exports.filterSyncedGroupUsers = filterSyncedGroupUsers;
@@ -1,4 +1,9 @@
1
1
  import { UserRole, UserWithRoles } from '../types/UserRole';
2
+ /**
3
+ * Get the user id for a `userRole`, either a `UserRole` or `EntityUserRole`.
4
+ * @param userRole The user role
5
+ */
6
+ export declare const getUserId: (userRole: UserRole) => string;
2
7
  /**
3
8
  * Get whether or not the `userRole` has a prop `isExternal` and it is `true`.
4
9
  * @param userRole The user role
@@ -19,3 +24,4 @@ export declare const sortByRole: (roles: string[]) => (a: UserRole, b: UserRole)
19
24
  * @param roles Roles ordered in descing access level
20
25
  */
21
26
  export declare const sortByHighestAccessRole: (roles: string[]) => (a: UserWithRoles, b: UserWithRoles) => 0 | 1 | -1;
27
+ export declare const convertToUserWithRoles: <TUserRole extends UserRole = UserRole>(userRole: TUserRole) => UserWithRoles<TUserRole>;
@@ -1,7 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.sortByHighestAccessRole = exports.sortByRole = exports.getRoleText = exports.isExternal = void 0;
3
+ exports.convertToUserWithRoles = exports.sortByHighestAccessRole = exports.sortByRole = exports.getRoleText = exports.isExternal = exports.getUserId = void 0;
4
4
  var baseRole_1 = require("./baseRole");
5
+ /**
6
+ * Get the user id for a `userRole`, either a `UserRole` or `EntityUserRole`.
7
+ * @param userRole The user role
8
+ */
9
+ var getUserId = function (userRole) {
10
+ return Object.prototype.hasOwnProperty.call(userRole, 'userId') ? userRole.userId : userRole.id;
11
+ };
12
+ exports.getUserId = getUserId;
5
13
  /**
6
14
  * Get whether or not the `userRole` has a prop `isExternal` and it is `true`.
7
15
  * @param userRole The user role
@@ -46,3 +54,15 @@ var sortByHighestAccessRole = function (roles) { return function (a, b) {
46
54
  return 0;
47
55
  }; };
48
56
  exports.sortByHighestAccessRole = sortByHighestAccessRole;
57
+ var convertToUserWithRoles = function (userRole) {
58
+ var userId = exports.getUserId(userRole);
59
+ return {
60
+ id: userId,
61
+ firstName: userRole.firstName,
62
+ lastName: userRole.lastName,
63
+ email: userRole.email,
64
+ uid: userRole.uid,
65
+ roles: [userRole]
66
+ };
67
+ };
68
+ exports.convertToUserWithRoles = convertToUserWithRoles;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "studiokit-scaffolding-js",
3
- "version": "4.3.20",
3
+ "version": "4.4.0",
4
4
  "description": "Common scaffolding for Studio apps at Purdue",
5
5
  "repository": "https://gitlab.com/purdue-informatics/studiokit/studiokit-scaffolding-js",
6
6
  "license": "MIT",
@@ -92,7 +92,7 @@
92
92
  "lodash": "^4.17.20",
93
93
  "mixin-deep": "^1.3.2",
94
94
  "set-value": "^2.0.1",
95
- "studiokit-net-js": "^4.0.2"
95
+ "studiokit-net-js": "^4.1.2"
96
96
  },
97
97
  "dependencies": {
98
98
  "@material-ui/core": "^4.11.3",
@@ -145,7 +145,7 @@
145
145
  "redux-saga": "^1.1.3",
146
146
  "studiokit-auth-js": "^3.0.2",
147
147
  "studiokit-caliper-js": "^1.0.23",
148
- "studiokit-net-js": "^4.0.2",
148
+ "studiokit-net-js": "^4.1.2",
149
149
  "tachyons": "^4.12.0",
150
150
  "tslib": "^2.1.0",
151
151
  "uuid": "^8.3.2"