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.
- package/lib/components/Groups/ExternalGroups/Attach.d.ts +36 -0
- package/lib/components/Groups/ExternalGroups/Attach.js +194 -0
- package/lib/components/Groups/ExternalGroups/Table.d.ts +13 -0
- package/lib/components/Groups/ExternalGroups/Table.js +83 -0
- package/lib/components/UserRoles/index.d.ts +3 -1
- package/lib/components/UserRoles/index.js +7 -6
- package/package.json +3 -1
|
@@ -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
|
-
|
|
425
|
-
!!renderTableDescription && renderTableDescription(
|
|
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:
|
|
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.
|
|
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",
|