studiokit-scaffolding-js 4.8.0 → 4.9.0-alpha.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.
@@ -0,0 +1,36 @@
1
+ import { Dictionary } from 'lodash';
2
+ import { Component } from 'react';
3
+ import { ModelCollection } from 'studiokit-net-js';
4
+ import { ExternalGroup, GroupUserRole, LtiLaunch, OwnerSchedule, UniTimeGroup, UserInfo } from '../../../types';
5
+ export interface ExternalGroupsAttachProps {
6
+ userInfo: UserInfo;
7
+ canReadExternalGroups: boolean;
8
+ canConnectAnyExternalGroups: boolean;
9
+ canConnectOwnExternalGroups: boolean;
10
+ originalConnectedExternalGroups: Array<ExternalGroup | LtiLaunch>;
11
+ selectedExternalGroups: Array<ExternalGroup | LtiLaunch | UniTimeGroup>;
12
+ externalTermId: number;
13
+ handleSelectedExternalGroups: (externalGroups: Array<ExternalGroup | LtiLaunch | UniTimeGroup>) => void;
14
+ groupUserRoles: ModelCollection<GroupUserRole>;
15
+ disabled?: boolean;
16
+ disabledInfoMessage?: string | JSX.Element;
17
+ }
18
+ interface ExternalGroupsAttachState {
19
+ ownerSchedules?: Dictionary<OwnerSchedule>;
20
+ isUniTimeScheduleLoadingDone: boolean;
21
+ isShowingErrorAlert: boolean;
22
+ }
23
+ export declare class ExternalGroupsAttach extends Component<ExternalGroupsAttachProps, ExternalGroupsAttachState> {
24
+ constructor(props: ExternalGroupsAttachProps);
25
+ componentDidMount(): void;
26
+ componentWillUnmount(): void;
27
+ componentDidUpdate(prevProps: Readonly<ExternalGroupsAttachProps>): void;
28
+ setOwnerSchedules: (groupUserRoles: GroupUserRole[], externalTermId: number, selectedExternalGroups: Array<ExternalGroup | LtiLaunch | UniTimeGroup>) => void;
29
+ handleSelectExternalGroups: (event: any) => void;
30
+ getOwnerUniTimeGroups: (ownerSchedule: OwnerSchedule, userId: string, externalTermId: number) => void;
31
+ setUserUniTimeGroups: (userId: string, externalGroups: UniTimeGroup[]) => void;
32
+ displayOwnerSchedules: (ownerSchedules: Dictionary<OwnerSchedule>) => (JSX.Element | undefined)[];
33
+ displayUniTimeGroups: (externalGroups: UniTimeGroup[]) => (JSX.Element | null)[];
34
+ render(): JSX.Element;
35
+ }
36
+ export {};
@@ -0,0 +1,194 @@
1
+ "use strict";
2
+ var __extends = (this && this.__extends) || (function () {
3
+ var extendStatics = function (d, b) {
4
+ extendStatics = Object.setPrototypeOf ||
5
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
7
+ return extendStatics(d, b);
8
+ };
9
+ return function (d, b) {
10
+ extendStatics(d, b);
11
+ function __() { this.constructor = d; }
12
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
13
+ };
14
+ })();
15
+ var __importDefault = (this && this.__importDefault) || function (mod) {
16
+ return (mod && mod.__esModule) ? mod : { "default": mod };
17
+ };
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.ExternalGroupsAttach = void 0;
20
+ var lodash_1 = require("lodash");
21
+ var react_1 = __importDefault(require("react"));
22
+ var react_2 = require("react");
23
+ var react_bootstrap_1 = require("react-bootstrap");
24
+ var studiokit_net_js_1 = require("studiokit-net-js");
25
+ var uuid_1 = require("uuid");
26
+ var constants_1 = require("../../../constants");
27
+ var actionCreator_1 = require("../../../redux/actionCreator");
28
+ var model_1 = require("../../../utils/model");
29
+ var shard_1 = require("../../../utils/shard");
30
+ var user_1 = require("../../../utils/user");
31
+ var AlertWithIcon_1 = __importDefault(require("../../AlertWithIcon"));
32
+ var Loading_1 = __importDefault(require("../../Loading"));
33
+ var ExternalGroupsAttach = /** @class */ (function (_super) {
34
+ __extends(ExternalGroupsAttach, _super);
35
+ function ExternalGroupsAttach(props) {
36
+ var _this = _super.call(this, props) || this;
37
+ _this.setOwnerSchedules = function (groupUserRoles, externalTermId, selectedExternalGroups) {
38
+ var _a = _this.props, canConnectAnyExternalGroups = _a.canConnectAnyExternalGroups, canConnectOwnExternalGroups = _a.canConnectOwnExternalGroups, userInfo = _a.userInfo;
39
+ var owners = groupUserRoles.filter(function (groupUserRole) {
40
+ return groupUserRole.role === constants_1.BASE_ROLE.GROUP_OWNER;
41
+ });
42
+ var ownersInitialScheduleData = {};
43
+ owners.forEach(function (owner) {
44
+ lodash_1.set(ownersInitialScheduleData, [owner.userId], {
45
+ hookId: uuid_1.v4(),
46
+ status: canConnectAnyExternalGroups || (userInfo.id === owner.id && canConnectOwnExternalGroups)
47
+ ? constants_1.MODEL_STATUS.UNINITIALIZED
48
+ : constants_1.MODEL_STATUS.READY,
49
+ owner: owner,
50
+ externalGroups: !(canConnectAnyExternalGroups ||
51
+ (userInfo.id === owner.id && canConnectOwnExternalGroups))
52
+ ? selectedExternalGroups.filter(function (seg) { return seg.userId === owner.id; })
53
+ : undefined
54
+ });
55
+ });
56
+ _this.setState({
57
+ ownerSchedules: ownersInitialScheduleData,
58
+ isUniTimeScheduleLoadingDone: false
59
+ }, function () {
60
+ return lodash_1.forEach(ownersInitialScheduleData, function (ownerSchedule, userId) {
61
+ return _this.getOwnerUniTimeGroups(ownerSchedule, userId, externalTermId);
62
+ });
63
+ });
64
+ };
65
+ _this.handleSelectExternalGroups = function (event) {
66
+ var externalId = event.target.value;
67
+ var checked = event.target.checked;
68
+ var _a = _this.props, originalConnectedExternalGroups = _a.originalConnectedExternalGroups, selectedExternalGroups = _a.selectedExternalGroups;
69
+ var allOwnerExternalGroups = lodash_1.map(_this.state.ownerSchedules, function (os) { return os.externalGroups; }).reduce(function (a, b) {
70
+ return a.concat(b);
71
+ });
72
+ var selectedExternalGroupsCopy = selectedExternalGroups.slice();
73
+ if (checked) {
74
+ var originalConnectedExternalGroup = originalConnectedExternalGroups.find(function (oeg) { return oeg.externalId === externalId; });
75
+ var selectedExternalGroup = originalConnectedExternalGroup
76
+ ? originalConnectedExternalGroup
77
+ : allOwnerExternalGroups === null || allOwnerExternalGroups === void 0 ? void 0 : allOwnerExternalGroups.find(function (ao) { return ao.externalId === externalId; });
78
+ if (selectedExternalGroup) {
79
+ selectedExternalGroupsCopy.push(selectedExternalGroup);
80
+ }
81
+ }
82
+ else {
83
+ lodash_1.remove(selectedExternalGroupsCopy, function (seg) { return seg.externalId === externalId; });
84
+ }
85
+ _this.props.handleSelectedExternalGroups(selectedExternalGroupsCopy);
86
+ };
87
+ _this.getOwnerUniTimeGroups = function (ownerSchedule, userId, externalTermId) {
88
+ if (shard_1.isPurdueShard() && ownerSchedule.status === constants_1.MODEL_STATUS.UNINITIALIZED && !ownerSchedule.externalGroups) {
89
+ studiokit_net_js_1.hooks.registerNoStoreActionHook(ownerSchedule.hookId, function (data) {
90
+ studiokit_net_js_1.hooks.unregisterNoStoreActionHook(ownerSchedule.hookId);
91
+ if (data && data.errorData) {
92
+ _this.setState({ isShowingErrorAlert: true, isUniTimeScheduleLoadingDone: true });
93
+ }
94
+ else {
95
+ _this.setUserUniTimeGroups(userId, data.externalGroups);
96
+ }
97
+ });
98
+ actionCreator_1.dispatchAction(studiokit_net_js_1.NET_ACTION.DATA_REQUESTED, {
99
+ modelName: 'uniTimeInstructorSchedule',
100
+ queryParams: {
101
+ externalTermId: externalTermId,
102
+ userId: userId
103
+ },
104
+ noStore: true,
105
+ guid: ownerSchedule.hookId
106
+ });
107
+ }
108
+ };
109
+ _this.setUserUniTimeGroups = function (userId, externalGroups) {
110
+ // Setting the user's course sections load status to be ready
111
+ var ownerSchedules = _this.state.ownerSchedules || {};
112
+ ownerSchedules[userId].status = constants_1.MODEL_STATUS.READY;
113
+ ownerSchedules[userId].externalGroups = externalGroups;
114
+ var isUniTimeScheduleLoadingDone = lodash_1.every(ownerSchedules, function (os) { return os.status === constants_1.MODEL_STATUS.READY; });
115
+ _this.setState({
116
+ ownerSchedules: ownerSchedules,
117
+ isUniTimeScheduleLoadingDone: isUniTimeScheduleLoadingDone
118
+ });
119
+ };
120
+ _this.displayOwnerSchedules = function (ownerSchedules) {
121
+ return lodash_1.map(ownerSchedules, function (os) {
122
+ if (!!os.externalGroups && os.externalGroups.length > 0) {
123
+ return (react_1.default.createElement("div", { key: os.hookId },
124
+ react_1.default.createElement("h4", null, user_1.displayName(os.owner)),
125
+ _this.displayUniTimeGroups(os.externalGroups)));
126
+ }
127
+ });
128
+ };
129
+ _this.displayUniTimeGroups = function (externalGroups) {
130
+ var _a = _this.props, selectedExternalGroups = _a.selectedExternalGroups, canConnectAnyExternalGroups = _a.canConnectAnyExternalGroups, canConnectOwnExternalGroups = _a.canConnectOwnExternalGroups, userInfo = _a.userInfo, disabled = _a.disabled;
131
+ return lodash_1.orderBy(externalGroups, ['description']).map(function (eg, index) {
132
+ var isConnected = selectedExternalGroups.some(function (seg) {
133
+ return seg.externalId === eg.externalId &&
134
+ seg.externalProviderId === eg.externalProviderId &&
135
+ seg.userId === eg.userId;
136
+ });
137
+ if (canConnectAnyExternalGroups ||
138
+ (userInfo.id === eg.userId && canConnectOwnExternalGroups) ||
139
+ isConnected) {
140
+ return (react_1.default.createElement(react_bootstrap_1.FormCheck, { id: "external-group-" + eg.id, type: "checkbox", key: index, onChange: _this.handleSelectExternalGroups, value: eg.externalId, checked: isConnected, disabled: (userInfo.id !== eg.userId && !canConnectAnyExternalGroups) || disabled, label: eg.name + " " + (eg.description ? "(" + eg.description + ")" : '') }));
141
+ }
142
+ return null;
143
+ });
144
+ };
145
+ _this.state = {
146
+ ownerSchedules: undefined,
147
+ isUniTimeScheduleLoadingDone: false,
148
+ isShowingErrorAlert: false
149
+ };
150
+ return _this;
151
+ }
152
+ ExternalGroupsAttach.prototype.componentDidMount = function () {
153
+ var _a = this.props, groupUserRoles = _a.groupUserRoles, externalTermId = _a.externalTermId, selectedExternalGroups = _a.selectedExternalGroups;
154
+ this.setOwnerSchedules(model_1.getModelArray(groupUserRoles), externalTermId, selectedExternalGroups);
155
+ };
156
+ ExternalGroupsAttach.prototype.componentWillUnmount = function () {
157
+ var ownerSchedules = this.state.ownerSchedules;
158
+ lodash_1.forEach(ownerSchedules, function (os) { return studiokit_net_js_1.hooks.unregisterNoStoreActionHook(os.hookId); });
159
+ };
160
+ ExternalGroupsAttach.prototype.componentDidUpdate = function (prevProps) {
161
+ var prevExternalTermId = prevProps.externalTermId, prevGroupUserRoles = prevProps.groupUserRoles;
162
+ var _a = this.props, externalTermId = _a.externalTermId, groupUserRoles = _a.groupUserRoles, selectedExternalGroups = _a.selectedExternalGroups;
163
+ // Assumes group user roles are changing one at a time. Can be made fancier if the need arises
164
+ if (!!prevGroupUserRoles &&
165
+ !!groupUserRoles &&
166
+ (prevExternalTermId !== externalTermId ||
167
+ Object.keys(prevGroupUserRoles).length !== Object.keys(groupUserRoles).length)) {
168
+ this.setOwnerSchedules(model_1.getModelArray(groupUserRoles), externalTermId, selectedExternalGroups);
169
+ }
170
+ };
171
+ ExternalGroupsAttach.prototype.render = function () {
172
+ var _this = this;
173
+ var disabledInfoMessage = this.props.disabledInfoMessage;
174
+ var _a = this.state, ownerSchedules = _a.ownerSchedules, isUniTimeScheduleLoadingDone = _a.isUniTimeScheduleLoadingDone, isShowingErrorAlert = _a.isShowingErrorAlert;
175
+ var hasAnyExternalGroups = lodash_1.some(ownerSchedules, function (os) { return !!os.externalGroups && os.externalGroups.length > 0; });
176
+ return (react_1.default.createElement("div", null,
177
+ !isUniTimeScheduleLoadingDone && react_1.default.createElement(Loading_1.default, null),
178
+ isUniTimeScheduleLoadingDone && (react_1.default.createElement("div", null,
179
+ !hasAnyExternalGroups && (react_1.default.createElement(AlertWithIcon_1.default, { variant: "info" },
180
+ react_1.default.createElement("p", null, "No course sections eligible for roster sync."))),
181
+ !!disabledInfoMessage && hasAnyExternalGroups && (react_1.default.createElement(AlertWithIcon_1.default, { variant: "info" },
182
+ react_1.default.createElement("p", null, disabledInfoMessage))),
183
+ isShowingErrorAlert && (react_1.default.createElement(AlertWithIcon_1.default, { variant: "warning", onClose: function () {
184
+ return _this.setState({
185
+ isShowingErrorAlert: false
186
+ });
187
+ } },
188
+ react_1.default.createElement("p", { className: "ma0" }, "Oops! Something went wrong while loading. Please try again."))),
189
+ ' ',
190
+ hasAnyExternalGroups && !!ownerSchedules && (react_1.default.createElement(react_bootstrap_1.FormGroup, { className: "ml4 f6" }, this.displayOwnerSchedules(ownerSchedules)))))));
191
+ };
192
+ return ExternalGroupsAttach;
193
+ }(react_2.Component));
194
+ exports.ExternalGroupsAttach = ExternalGroupsAttach;
@@ -0,0 +1,13 @@
1
+ import { FunctionComponent, TableHTMLAttributes } from 'react';
2
+ import { ModelCollection } from 'studiokit-net-js';
3
+ import { ExternalGroup, Group, GroupUserRole, LtiLaunch, UniTimeGroup } from '../../../types';
4
+ export interface ExternalGroupsTableProps extends TableHTMLAttributes<Element> {
5
+ group: Partial<Group>;
6
+ externalGroups: Array<ExternalGroup | LtiLaunch | UniTimeGroup>;
7
+ hasGradePushEnabled: boolean;
8
+ hasAnyLtiExternalGroup: boolean;
9
+ canEditExternalGroups: boolean;
10
+ groupUserRoles?: ModelCollection<GroupUserRole>;
11
+ updateExternalGroup: (externalGroup: ExternalGroup | LtiLaunch | UniTimeGroup) => void;
12
+ }
13
+ export declare const ExternalGroupsTable: FunctionComponent<ExternalGroupsTableProps>;
@@ -0,0 +1,83 @@
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
+ };
24
+ var __importDefault = (this && this.__importDefault) || function (mod) {
25
+ return (mod && mod.__esModule) ? mod : { "default": mod };
26
+ };
27
+ Object.defineProperty(exports, "__esModule", { value: true });
28
+ exports.ExternalGroupsTable = void 0;
29
+ var ToggleButton_1 = __importDefault(require("@material-ui/lab/ToggleButton"));
30
+ var ToggleButtonGroup_1 = __importDefault(require("@material-ui/lab/ToggleButtonGroup"));
31
+ var lodash_1 = require("lodash");
32
+ var react_1 = __importDefault(require("react"));
33
+ var react_super_responsive_table_1 = require("react-super-responsive-table");
34
+ var constants_1 = require("../../../constants");
35
+ var model_1 = require("../../../utils/model");
36
+ var user_1 = require("../../../utils/user");
37
+ var shouldShowAutoGradePushColumn = function (hasAnyLtiExternalGroup, group, hasGradePushEnabled) { return (hasAnyLtiExternalGroup && lodash_1.isEmpty(group)) || hasGradePushEnabled; };
38
+ var renderTableHeaderRow = function (hasAnyLtiExternalGroup, group, hasGradePushEnabled) {
39
+ var headerCells = ['Course Name', 'Course Description', 'Instructor'];
40
+ if (shouldShowAutoGradePushColumn(hasAnyLtiExternalGroup, group, hasGradePushEnabled)) {
41
+ headerCells.push('Grade Push');
42
+ }
43
+ return (react_1.default.createElement(react_super_responsive_table_1.Tr, null, headerCells.map(function (value, i) { return (react_1.default.createElement(react_super_responsive_table_1.Th, { key: i }, value)); })));
44
+ };
45
+ var renderTableBodyRow = function (key, externalGroup, owner, hasGradePushEnabled, hasAnyLtiExternalGroup, canEditExternalGroups, group, updateExternalGroup) {
46
+ var cells = [
47
+ externalGroup.name,
48
+ react_1.default.createElement("span", { style: { overflowWrap: 'anywhere' } }, externalGroup.description),
49
+ owner ? "" + user_1.displayName(owner) : ''
50
+ ];
51
+ // brand new LTI group or editing a group that has grade push enabled
52
+ if (shouldShowAutoGradePushColumn(hasAnyLtiExternalGroup, group, hasGradePushEnabled)) {
53
+ if (canEditExternalGroups) {
54
+ cells.push(react_1.default.createElement(ToggleButtonGroup_1.default, { value: externalGroup.isAutoGradePushEnabled, exclusive: true, onChange: function (_, newValue) {
55
+ // do not allow "turning off" any of the selections
56
+ if (newValue === null)
57
+ return;
58
+ updateExternalGroup(__assign(__assign({}, externalGroup), { isAutoGradePushEnabled: newValue }));
59
+ }, "aria-label": "auto grade push" },
60
+ react_1.default.createElement(ToggleButton_1.default, { value: true }, "Automatic"),
61
+ react_1.default.createElement(ToggleButton_1.default, { value: false }, "Manual")));
62
+ }
63
+ else {
64
+ cells.push(externalGroup.isAutoGradePushEnabled ? 'Automatic' : 'Manual');
65
+ }
66
+ }
67
+ return (react_1.default.createElement(react_super_responsive_table_1.Tr, { key: key }, cells.map(function (value, i) { return (react_1.default.createElement(react_super_responsive_table_1.Td, { key: i }, value)); })));
68
+ };
69
+ var ExternalGroupsTable = function (_a) {
70
+ var group = _a.group, externalGroups = _a.externalGroups, hasGradePushEnabled = _a.hasGradePushEnabled, hasAnyLtiExternalGroup = _a.hasAnyLtiExternalGroup, canEditExternalGroups = _a.canEditExternalGroups, groupUserRoles = _a.groupUserRoles, updateExternalGroup = _a.updateExternalGroup, other = __rest(_a, ["group", "externalGroups", "hasGradePushEnabled", "hasAnyLtiExternalGroup", "canEditExternalGroups", "groupUserRoles", "updateExternalGroup"]) // for passing aria-describedby to tables
71
+ ;
72
+ return (react_1.default.createElement("div", { className: "table-container" },
73
+ react_1.default.createElement(react_super_responsive_table_1.Table, __assign({}, other, { className: "w-100 mb4" }),
74
+ react_1.default.createElement(react_super_responsive_table_1.Thead, null, renderTableHeaderRow(hasAnyLtiExternalGroup, group, hasGradePushEnabled)),
75
+ react_1.default.createElement(react_super_responsive_table_1.Tbody, null, externalGroups.map(function (externalGroup, i) {
76
+ var _a;
77
+ var owner = lodash_1.isEmpty(group) && !!groupUserRoles
78
+ ? model_1.getModelArray(groupUserRoles).find(function (gur) { return gur.userId === externalGroup.userId && gur.role === constants_1.BASE_ROLE.GROUP_OWNER; })
79
+ : (_a = group.owners) === null || _a === void 0 ? void 0 : _a.find(function (o) { return o.id === externalGroup.userId; });
80
+ return renderTableBodyRow(i, externalGroup, owner, hasGradePushEnabled, hasAnyLtiExternalGroup, canEditExternalGroups, group, updateExternalGroup);
81
+ })))));
82
+ };
83
+ exports.ExternalGroupsTable = ExternalGroupsTable;
@@ -9,6 +9,8 @@ export interface UserRolesReduxProps {
9
9
  canDeleteSelf?: boolean;
10
10
  }
11
11
  export interface UserRolesOwnProps extends CollectionComponentWrappedProps<UserRole> {
12
+ /** Should the component prevent modifications, independent of permissions? */
13
+ readOnly?: boolean;
12
14
  /** Is the current user allowed to delete their own user role? Overrides the value from redux. */
13
15
  canDeleteSelf?: boolean;
14
16
  /** If multiple roles allowed, each role is displayed per user, otherwise a select dropdown is displayed. */
@@ -104,5 +106,5 @@ export declare class UserRoles extends Component<UserRolesProps, UserRolesState>
104
106
  render(): JSX.Element;
105
107
  }
106
108
  export declare const mapStateToProps: (state: BaseReduxState, ownProps: UserRolesOwnProps) => UserRolesReduxProps;
107
- declare const _default: import("react-redux").ConnectedComponent<typeof UserRoles, Pick<React.ClassAttributes<UserRoles> & UserRolesProps, "externalProviders" | "model" | "ref" | "key" | "guid" | "load" | "modelName" | "pathParams" | "modelStatus" | "queryParams" | "disableAutoLoad" | "modelArray" | "stopPeriodicLoad" | "create" | "update" | "delete" | "previousModelStatus" | "fetchingId" | "textForRole" | "entityName" | "defaultRole" | "roleDescriptions" | "renderAddDescription" | "isUpdateDisabled" | "isDeleteDisabled" | "allowMultipleRoles" | "requiredRole" | "isAddDisabled" | "modifyUserRoleActivityName" | "deleteOwnUserRoleActivityName" | "addRoleExcludeList" | "entity" | "filterUsers" | "onAdd" | "onUpdate" | "onRemove" | "renderTableDescription" | "singularArticleForRole"> & UserRolesOwnProps>;
109
+ declare const _default: import("react-redux").ConnectedComponent<typeof UserRoles, Pick<React.ClassAttributes<UserRoles> & UserRolesProps, "externalProviders" | "model" | "ref" | "key" | "readOnly" | "guid" | "load" | "modelName" | "pathParams" | "modelStatus" | "queryParams" | "disableAutoLoad" | "modelArray" | "stopPeriodicLoad" | "create" | "update" | "delete" | "previousModelStatus" | "fetchingId" | "textForRole" | "entityName" | "defaultRole" | "roleDescriptions" | "renderAddDescription" | "isUpdateDisabled" | "isDeleteDisabled" | "allowMultipleRoles" | "requiredRole" | "isAddDisabled" | "modifyUserRoleActivityName" | "deleteOwnUserRoleActivityName" | "addRoleExcludeList" | "entity" | "filterUsers" | "onAdd" | "onUpdate" | "onRemove" | "renderTableDescription" | "singularArticleForRole"> & UserRolesOwnProps>;
108
110
  export default _default;
@@ -390,12 +390,13 @@ var UserRoles = /** @class */ (function (_super) {
390
390
  //#endregion Remove User
391
391
  UserRoles.prototype.render = function () {
392
392
  var _this = this;
393
- var _a = this.props, modelStatus = _a.modelStatus, canModify = _a.canModify, canDeleteSelf = _a.canDeleteSelf, allowMultipleRoles = _a.allowMultipleRoles, isAddDisabled = _a.isAddDisabled, isUpdateDisabled = _a.isUpdateDisabled, isDeleteDisabled = _a.isDeleteDisabled, defaultRole = _a.defaultRole, requiredRole = _a.requiredRole, roleDescriptions = _a.roleDescriptions, addRoleExcludeList = _a.addRoleExcludeList, entityName = _a.entityName, renderTableDescription = _a.renderTableDescription, renderAddDescription = _a.renderAddDescription;
393
+ var _a = this.props, modelStatus = _a.modelStatus, canModify = _a.canModify, readOnly = _a.readOnly, canDeleteSelf = _a.canDeleteSelf, allowMultipleRoles = _a.allowMultipleRoles, isAddDisabled = _a.isAddDisabled, isUpdateDisabled = _a.isUpdateDisabled, isDeleteDisabled = _a.isDeleteDisabled, defaultRole = _a.defaultRole, requiredRole = _a.requiredRole, roleDescriptions = _a.roleDescriptions, addRoleExcludeList = _a.addRoleExcludeList, entityName = _a.entityName, renderTableDescription = _a.renderTableDescription, renderAddDescription = _a.renderAddDescription;
394
394
  var _b = this.state, sortedUsers = _b.sortedUsers, isAdding = _b.isAdding, isUpdating = _b.isUpdating, isRemoving = _b.isRemoving, shouldResetAddForm = _b.shouldResetAddForm, shouldShowRemoveDialog = _b.shouldShowRemoveDialog, userRoleToUpdate = _b.userRoleToUpdate, userRoleToRemove = _b.userRoleToRemove, successMessage = _b.successMessage, existingMessage = _b.existingMessage, blockedMessage = _b.blockedMessage, failMessage = _b.failMessage;
395
395
  var addableRoleDescriptions = addRoleExcludeList
396
396
  ? lodash_1.pickBy(roleDescriptions, function (_, key) { return !addRoleExcludeList.includes(key); })
397
397
  : roleDescriptions;
398
398
  var roles = Object.keys(roleDescriptions);
399
+ var shouldRenderAsMutable = !readOnly && canModify;
399
400
  return (react_1.default.createElement(react_1.default.Fragment, null,
400
401
  !!successMessage && (react_1.default.createElement(AlertWithIcon_1.default, { id: "successMessageAlert", variant: "success", dismissible: true, onClose: function () {
401
402
  return _this.setState({
@@ -421,13 +422,13 @@ var UserRoles = /** @class */ (function (_super) {
421
422
  });
422
423
  } },
423
424
  react_1.default.createElement("p", { className: "pre-wrap" }, failMessage))),
424
- canModify && (react_1.default.createElement(Add_1.default, { id: "entityUserRolesAdd", disabled: isAddDisabled, entityName: entityName, defaultRole: defaultRole, roleDescriptions: addableRoleDescriptions, renderAddDescription: renderAddDescription, textForRole: this.textForRole, isAddingUsersToRole: isAdding, shouldReset: shouldResetAddForm, addUserRoles: this.addUserRoles })),
425
- !!renderTableDescription && renderTableDescription(canModify),
425
+ shouldRenderAsMutable && (react_1.default.createElement(Add_1.default, { id: "entityUserRolesAdd", disabled: isAddDisabled, entityName: entityName, defaultRole: defaultRole, roleDescriptions: addableRoleDescriptions, renderAddDescription: renderAddDescription, textForRole: this.textForRole, isAddingUsersToRole: isAdding, shouldReset: shouldResetAddForm, addUserRoles: this.addUserRoles })),
426
+ !!renderTableDescription && renderTableDescription(shouldRenderAsMutable),
426
427
  react_1.default.createElement(react_bootstrap_1.Row, { className: "mt3" },
427
428
  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(Context_1.UserRolesContext.Provider, { value: {
428
- isUpdateDisabled: isUpdateDisabled,
429
- isDeleteDisabled: isDeleteDisabled,
430
- canModify: canModify,
429
+ isUpdateDisabled: isUpdateDisabled || readOnly,
430
+ isDeleteDisabled: isDeleteDisabled || readOnly,
431
+ canModify: shouldRenderAsMutable,
431
432
  canDeleteSelf: canDeleteSelf,
432
433
  allowMultipleRoles: allowMultipleRoles,
433
434
  roles: roles,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "studiokit-scaffolding-js",
3
- "version": "4.8.0",
3
+ "version": "4.9.0-alpha.2",
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",
@@ -97,6 +97,7 @@
97
97
  "dependencies": {
98
98
  "@material-ui/core": "^4.11.3",
99
99
  "@material-ui/icons": "^4.11.2",
100
+ "@material-ui/lab": "^4.0.0-alpha.57",
100
101
  "@microsoft/applicationinsights-web": "^2.5.11",
101
102
  "@redux-saga/types": "^1.1.0",
102
103
  "@sentry/react": "^7.38.0",
@@ -140,6 +141,7 @@
140
141
  "react-router": "^5.2.0",
141
142
  "react-router-bootstrap": "^0.25.0",
142
143
  "react-router-dom": "^5.2.0",
144
+ "react-super-responsive-table": "^5.2.0",
143
145
  "react-table": "^6.11.5",
144
146
  "redux": "^4.0.5",
145
147
  "redux-devtools-extension": "^2.13.8",