@openedx/frontend-app-instructor-dashboard 1.0.0-alpha.5 → 1.0.0-alpha.7
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/dist/app.js +0 -4
- package/dist/app.js.map +1 -1
- package/dist/app.scss +4 -0
- package/dist/components/UsernameFilter.d.ts +7 -0
- package/dist/components/UsernameFilter.js +19 -0
- package/dist/components/UsernameFilter.js.map +1 -0
- package/dist/components/messages.d.ts +5 -0
- package/dist/components/messages.js +5 -0
- package/dist/components/messages.js.map +1 -1
- package/dist/courseTeam/CourseTeamPage.js +9 -2
- package/dist/courseTeam/CourseTeamPage.js.map +1 -1
- package/dist/courseTeam/components/MembersContent.d.ts +2 -0
- package/dist/courseTeam/components/MembersContent.js +60 -0
- package/dist/courseTeam/components/MembersContent.js.map +1 -0
- package/dist/courseTeam/components/RolesContent.d.ts +2 -0
- package/dist/courseTeam/components/RolesContent.js +6 -0
- package/dist/courseTeam/components/RolesContent.js.map +1 -0
- package/dist/courseTeam/data/api.d.ts +4 -0
- package/dist/courseTeam/data/api.js +30 -0
- package/dist/courseTeam/data/api.js.map +1 -0
- package/dist/courseTeam/data/apiHook.d.ts +3 -0
- package/dist/courseTeam/data/apiHook.js +14 -0
- package/dist/courseTeam/data/apiHook.js.map +1 -0
- package/dist/courseTeam/data/queryKeys.d.ts +7 -0
- package/dist/courseTeam/data/queryKeys.js +14 -0
- package/dist/courseTeam/data/queryKeys.js.map +1 -0
- package/dist/courseTeam/messages.d.ts +58 -0
- package/dist/courseTeam/messages.js +60 -0
- package/dist/courseTeam/messages.js.map +1 -0
- package/dist/courseTeam/types.d.ts +15 -0
- package/dist/courseTeam/types.js +2 -0
- package/dist/courseTeam/types.js.map +1 -0
- package/dist/data/api.d.ts +1 -1
- package/dist/data/api.js +2 -3
- package/dist/data/api.js.map +1 -1
- package/dist/dateExtensions/components/DateExtensionsList.js +2 -13
- package/dist/dateExtensions/components/DateExtensionsList.js.map +1 -1
- package/dist/dateExtensions/messages.d.ts +0 -5
- package/dist/dateExtensions/messages.js +0 -5
- package/dist/dateExtensions/messages.js.map +1 -1
- package/package.json +1 -1
package/dist/app.js
CHANGED
package/dist/app.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,KAAK,MAAM,YAAY,CAAC;AAC/B,OAAO,QAAQ,MAAM,eAAe,CAAC;AAErC,MAAM,GAAG,GAAQ;IACf,KAAK;IACL,MAAM;IACN,QAAQ;IACR,KAAK;
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,KAAK,MAAM,YAAY,CAAC;AAC/B,OAAO,QAAQ,MAAM,eAAe,CAAC;AAErC,MAAM,GAAG,GAAQ;IACf,KAAK;IACL,MAAM;IACN,QAAQ;IACR,KAAK;CACN,CAAC;AAEF,eAAe,GAAG,CAAC","sourcesContent":["import { App } from '@openedx/frontend-base';\nimport { appId } from '@src/constants';\nimport routes from '@src/routes';\nimport slots from '@src/slots';\nimport provides from '@src/provides';\n\nconst app: App = {\n appId,\n routes,\n provides,\n slots,\n};\n\nexport default app;\n"]}
|
package/dist/app.scss
CHANGED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useIntl } from '@openedx/frontend-base';
|
|
3
|
+
import { FormControl, Icon } from '@openedx/paragon';
|
|
4
|
+
import { Search } from '@openedx/paragon/icons';
|
|
5
|
+
import { useDebouncedFilter } from '../hooks/useDebouncedFilter';
|
|
6
|
+
import messages from '../components/messages';
|
|
7
|
+
const UsernameFilter = ({ column: { filterValue, setFilter } }) => {
|
|
8
|
+
const intl = useIntl();
|
|
9
|
+
const { inputValue, handleChange } = useDebouncedFilter({
|
|
10
|
+
filterValue,
|
|
11
|
+
setFilter,
|
|
12
|
+
});
|
|
13
|
+
const handleInputChange = (e) => {
|
|
14
|
+
handleChange(e.target.value);
|
|
15
|
+
};
|
|
16
|
+
return (_jsx(FormControl, { className: "mb-0 username", onChange: handleInputChange, placeholder: intl.formatMessage(messages.searchPlaceholder), trailingElement: _jsx(Icon, { src: Search }), value: inputValue }));
|
|
17
|
+
};
|
|
18
|
+
export default UsernameFilter;
|
|
19
|
+
//# sourceMappingURL=UsernameFilter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UsernameFilter.js","sourceRoot":"","sources":["../../src/components/UsernameFilter.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,QAAQ,MAAM,0BAA0B,CAAC;AAEhD,MAAM,cAAc,GAAG,CAAC,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,EAA2E,EAAE,EAAE;IACzI,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,GAAG,kBAAkB,CAAC;QACtD,WAAW;QACX,SAAS;KACV,CAAC,CAAC;IAEH,MAAM,iBAAiB,GAAG,CAAC,CAAsC,EAAE,EAAE;QACnE,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC,CAAC;IAEF,OAAO,CACL,KAAC,WAAW,IACV,SAAS,EAAC,eAAe,EACzB,QAAQ,EAAE,iBAAiB,EAC3B,WAAW,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAC3D,eAAe,EAAE,KAAC,IAAI,IAAC,GAAG,EAAE,MAAM,GAAI,EACtC,KAAK,EAAE,UAAU,GACjB,CACH,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,cAAc,CAAC","sourcesContent":["import { useIntl } from '@openedx/frontend-base';\nimport { FormControl, Icon } from '@openedx/paragon';\nimport { Search } from '@openedx/paragon/icons';\nimport { useDebouncedFilter } from '@src/hooks/useDebouncedFilter';\nimport messages from '@src/components/messages';\n\nconst UsernameFilter = ({ column: { filterValue, setFilter } }: { column: { filterValue: string, setFilter: (value: string) => void } }) => {\n const intl = useIntl();\n const { inputValue, handleChange } = useDebouncedFilter({\n filterValue,\n setFilter,\n });\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n handleChange(e.target.value);\n };\n\n return (\n <FormControl\n className=\"mb-0 username\"\n onChange={handleInputChange}\n placeholder={intl.formatMessage(messages.searchPlaceholder)}\n trailingElement={<Icon src={Search} />}\n value={inputValue}\n />\n );\n};\n\nexport default UsernameFilter;\n"]}
|
|
@@ -115,6 +115,11 @@ const messages = defineMessages({
|
|
|
115
115
|
defaultMessage: 'Could not find student matching identifier: {identifier}',
|
|
116
116
|
description: 'Error message displayed when a learner cannot be found based on the provided identifier (email or username)',
|
|
117
117
|
},
|
|
118
|
+
searchPlaceholder: {
|
|
119
|
+
id: 'instruct.usernameFilter.searchPlaceholder',
|
|
120
|
+
defaultMessage: 'Search By Username or Email',
|
|
121
|
+
description: 'Placeholder text for the username filter input',
|
|
122
|
+
}
|
|
118
123
|
});
|
|
119
124
|
export default messages;
|
|
120
125
|
//# sourceMappingURL=messages.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/components/messages.ts"],"names":[],"mappings":"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","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n select: {\n id: 'instruct.specifyLearner.select',\n defaultMessage: 'Select',\n description: 'Label for select dropdown in specify learner field',\n },\n specifyLearner: {\n id: 'instruct.specifyLearner.label',\n defaultMessage: 'Specify Learner:',\n description: 'Label for specify learner field',\n },\n specifyLearnerPlaceholder: {\n id: 'instruct.specifyLearner.placeholder',\n defaultMessage: 'Learner email address or username',\n description: 'Placeholder text for specify learner input field',\n },\n pageNotFoundHeader: {\n id: 'instruct.pageNotFound.header',\n defaultMessage: 'Page not found',\n description: 'Header for page not found error',\n },\n pageNotFoundBody: {\n id: 'instruct.pageNotFound.body',\n defaultMessage: \"The page you're looking for is unavailable or there's an error in the URL. Please check the URL and try again.\",\n description: 'Body text for page not found error',\n },\n pendingTasksTitle: {\n id: 'instruct.pendingTasks.section.title',\n defaultMessage: 'Pending Tasks',\n description: 'Title for the pending tasks section',\n },\n noTasksMessage: {\n id: 'instruct.pendingTasks.section.noTasks',\n defaultMessage: 'No tasks currently running.',\n description: 'Message displayed when there are no pending tasks',\n },\n taskTypeColumnName: {\n id: 'instruct.pendingTasks.table.column.taskType',\n defaultMessage: 'Task Type',\n description: 'Column name for task type in pending tasks table',\n },\n taskInputColumnName: {\n id: 'instruct.pendingTasks.table.column.taskInput',\n defaultMessage: 'Task Input',\n description: 'Column name for task input in pending tasks table',\n },\n taskIdColumnName: {\n id: 'instruct.pendingTasks.table.column.taskId',\n defaultMessage: 'Task ID',\n description: 'Column name for task ID in pending tasks table',\n },\n requesterColumnName: {\n id: 'instruct.pendingTasks.table.column.requester',\n defaultMessage: 'Requester',\n description: 'Column name for requester in pending tasks table',\n },\n taskStateColumnName: {\n id: 'instruct.pendingTasks.table.column.taskState',\n defaultMessage: 'Task State',\n description: 'Column name for task state in pending tasks table',\n },\n createdColumnName: {\n id: 'instruct.pendingTasks.table.column.created',\n defaultMessage: 'Created',\n description: 'Column name for created date in pending tasks table',\n },\n taskOutputColumnName: {\n id: 'instruct.pendingTasks.table.column.taskOutput',\n defaultMessage: 'Task Output',\n description: 'Column name for task output in pending tasks table',\n },\n durationColumnName: {\n id: 'instruct.pendingTasks.table.column.duration',\n defaultMessage: 'Duration (sec)',\n description: 'Column name for duration in pending tasks table',\n },\n statusColumnName: {\n id: 'instruct.pendingTasks.table.column.status',\n defaultMessage: 'Status',\n description: 'Column name for status in pending tasks table',\n },\n taskMessageColumnName: {\n id: 'instruct.pendingTasks.table.column.taskMessage',\n defaultMessage: 'Task Message',\n description: 'Column name for task message in pending tasks table',\n },\n downloadCSVTitle: {\n id: 'instruct.csvComponent.downloadCSVTitle',\n defaultMessage: 'Upload CSV File',\n description: 'Title for the upload CSV file section'\n },\n downloadCSVDescription: {\n id: 'instruct.csvComponent.downloadCSVDescription',\n defaultMessage: 'Only properly formatted CSV files will be accepted',\n description: 'Description for the upload CSV file section'\n },\n viewCSVTemplate: {\n id: 'instruct.csvComponent.viewCSVTemplate',\n defaultMessage: 'View Template',\n description: 'Label for the view CSV template link'\n },\n uploadingFileMessage: {\n id: 'instruct.csvComponent.uploadingFileMessage',\n defaultMessage: 'File chosen: {fileName}',\n description: 'Message displayed when a file is being uploaded, with the file name included'\n },\n change: {\n id: 'instruct.specifyLearner.change',\n defaultMessage: 'Change',\n description: 'Label for change button in specify learner field',\n },\n learnerNotFound: {\n id: 'instruct.specifyLearner.learnerNotFound',\n defaultMessage: 'Could not find student matching identifier: {identifier}',\n description: 'Error message displayed when a learner cannot be found based on the provided identifier (email or username)',\n },\n});\n\nexport default messages;\n"]}
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/components/messages.ts"],"names":[],"mappings":"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","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n select: {\n id: 'instruct.specifyLearner.select',\n defaultMessage: 'Select',\n description: 'Label for select dropdown in specify learner field',\n },\n specifyLearner: {\n id: 'instruct.specifyLearner.label',\n defaultMessage: 'Specify Learner:',\n description: 'Label for specify learner field',\n },\n specifyLearnerPlaceholder: {\n id: 'instruct.specifyLearner.placeholder',\n defaultMessage: 'Learner email address or username',\n description: 'Placeholder text for specify learner input field',\n },\n pageNotFoundHeader: {\n id: 'instruct.pageNotFound.header',\n defaultMessage: 'Page not found',\n description: 'Header for page not found error',\n },\n pageNotFoundBody: {\n id: 'instruct.pageNotFound.body',\n defaultMessage: \"The page you're looking for is unavailable or there's an error in the URL. Please check the URL and try again.\",\n description: 'Body text for page not found error',\n },\n pendingTasksTitle: {\n id: 'instruct.pendingTasks.section.title',\n defaultMessage: 'Pending Tasks',\n description: 'Title for the pending tasks section',\n },\n noTasksMessage: {\n id: 'instruct.pendingTasks.section.noTasks',\n defaultMessage: 'No tasks currently running.',\n description: 'Message displayed when there are no pending tasks',\n },\n taskTypeColumnName: {\n id: 'instruct.pendingTasks.table.column.taskType',\n defaultMessage: 'Task Type',\n description: 'Column name for task type in pending tasks table',\n },\n taskInputColumnName: {\n id: 'instruct.pendingTasks.table.column.taskInput',\n defaultMessage: 'Task Input',\n description: 'Column name for task input in pending tasks table',\n },\n taskIdColumnName: {\n id: 'instruct.pendingTasks.table.column.taskId',\n defaultMessage: 'Task ID',\n description: 'Column name for task ID in pending tasks table',\n },\n requesterColumnName: {\n id: 'instruct.pendingTasks.table.column.requester',\n defaultMessage: 'Requester',\n description: 'Column name for requester in pending tasks table',\n },\n taskStateColumnName: {\n id: 'instruct.pendingTasks.table.column.taskState',\n defaultMessage: 'Task State',\n description: 'Column name for task state in pending tasks table',\n },\n createdColumnName: {\n id: 'instruct.pendingTasks.table.column.created',\n defaultMessage: 'Created',\n description: 'Column name for created date in pending tasks table',\n },\n taskOutputColumnName: {\n id: 'instruct.pendingTasks.table.column.taskOutput',\n defaultMessage: 'Task Output',\n description: 'Column name for task output in pending tasks table',\n },\n durationColumnName: {\n id: 'instruct.pendingTasks.table.column.duration',\n defaultMessage: 'Duration (sec)',\n description: 'Column name for duration in pending tasks table',\n },\n statusColumnName: {\n id: 'instruct.pendingTasks.table.column.status',\n defaultMessage: 'Status',\n description: 'Column name for status in pending tasks table',\n },\n taskMessageColumnName: {\n id: 'instruct.pendingTasks.table.column.taskMessage',\n defaultMessage: 'Task Message',\n description: 'Column name for task message in pending tasks table',\n },\n downloadCSVTitle: {\n id: 'instruct.csvComponent.downloadCSVTitle',\n defaultMessage: 'Upload CSV File',\n description: 'Title for the upload CSV file section'\n },\n downloadCSVDescription: {\n id: 'instruct.csvComponent.downloadCSVDescription',\n defaultMessage: 'Only properly formatted CSV files will be accepted',\n description: 'Description for the upload CSV file section'\n },\n viewCSVTemplate: {\n id: 'instruct.csvComponent.viewCSVTemplate',\n defaultMessage: 'View Template',\n description: 'Label for the view CSV template link'\n },\n uploadingFileMessage: {\n id: 'instruct.csvComponent.uploadingFileMessage',\n defaultMessage: 'File chosen: {fileName}',\n description: 'Message displayed when a file is being uploaded, with the file name included'\n },\n change: {\n id: 'instruct.specifyLearner.change',\n defaultMessage: 'Change',\n description: 'Label for change button in specify learner field',\n },\n learnerNotFound: {\n id: 'instruct.specifyLearner.learnerNotFound',\n defaultMessage: 'Could not find student matching identifier: {identifier}',\n description: 'Error message displayed when a learner cannot be found based on the provided identifier (email or username)',\n },\n searchPlaceholder: {\n id: 'instruct.usernameFilter.searchPlaceholder',\n defaultMessage: 'Search By Username or Email',\n description: 'Placeholder text for the username filter input',\n }\n});\n\nexport default messages;\n"]}
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useIntl } from '@openedx/frontend-base';
|
|
3
|
+
import { Button, Tab, Tabs } from '@openedx/paragon';
|
|
4
|
+
import { Plus } from '@openedx/paragon/icons';
|
|
5
|
+
import MembersContent from '../courseTeam/components/MembersContent';
|
|
6
|
+
import RolesContent from '../courseTeam/components/RolesContent';
|
|
7
|
+
import messages from '../courseTeam/messages';
|
|
2
8
|
const CourseTeamPage = () => {
|
|
3
|
-
|
|
9
|
+
const intl = useIntl();
|
|
10
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "d-flex justify-content-between align-items-center mb-3", children: [_jsx("h3", { className: "text-primary-700 mb-0", children: intl.formatMessage(messages.courseTeamTitle) }), _jsx(Button, { iconBefore: Plus, variant: "primary", children: intl.formatMessage(messages.addTeamMember) })] }), _jsxs(Tabs, { children: [_jsx(Tab, { eventKey: "members", title: intl.formatMessage(messages.membersTab), children: _jsx(MembersContent, {}) }), _jsx(Tab, { eventKey: "roles", title: intl.formatMessage(messages.rolesTab), children: _jsx(RolesContent, {}) })] })] }));
|
|
4
11
|
};
|
|
5
12
|
export default CourseTeamPage;
|
|
6
13
|
//# sourceMappingURL=CourseTeamPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CourseTeamPage.js","sourceRoot":"","sources":["../../src/courseTeam/CourseTeamPage.tsx"],"names":[],"mappings":";AAAA,MAAM,cAAc,GAAG,GAAG,EAAE;IAC1B,OAAO,CACL,
|
|
1
|
+
{"version":3,"file":"CourseTeamPage.js","sourceRoot":"","sources":["../../src/courseTeam/CourseTeamPage.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC9C,OAAO,cAAc,MAAM,2CAA2C,CAAC;AACvE,OAAO,YAAY,MAAM,yCAAyC,CAAC;AACnE,OAAO,QAAQ,MAAM,0BAA0B,CAAC;AAEhD,MAAM,cAAc,GAAG,GAAG,EAAE;IAC1B,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IAEvB,OAAO,CACL,8BACE,eAAK,SAAS,EAAC,wDAAwD,aACrE,aAAI,SAAS,EAAC,uBAAuB,YAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,eAAe,CAAC,GAAM,EACzF,KAAC,MAAM,IAAC,UAAU,EAAE,IAAI,EAAE,OAAO,EAAC,SAAS,YAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAU,IAC7F,EACN,MAAC,IAAI,eACH,KAAC,GAAG,IAAC,QAAQ,EAAC,SAAS,EAAC,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,UAAU,CAAC,YACpE,KAAC,cAAc,KAAG,GACd,EACN,KAAC,GAAG,IAAC,QAAQ,EAAC,OAAO,EAAC,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC,YAChE,KAAC,YAAY,KAAG,GACZ,IACD,IACN,CACJ,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,cAAc,CAAC","sourcesContent":["import { useIntl } from '@openedx/frontend-base';\nimport { Button, Tab, Tabs } from '@openedx/paragon';\nimport { Plus } from '@openedx/paragon/icons';\nimport MembersContent from '@src/courseTeam/components/MembersContent';\nimport RolesContent from '@src/courseTeam/components/RolesContent';\nimport messages from '@src/courseTeam/messages';\n\nconst CourseTeamPage = () => {\n const intl = useIntl();\n\n return (\n <>\n <div className=\"d-flex justify-content-between align-items-center mb-3\">\n <h3 className=\"text-primary-700 mb-0\">{intl.formatMessage(messages.courseTeamTitle)}</h3>\n <Button iconBefore={Plus} variant=\"primary\">{intl.formatMessage(messages.addTeamMember)}</Button>\n </div>\n <Tabs>\n <Tab eventKey=\"members\" title={intl.formatMessage(messages.membersTab)}>\n <MembersContent />\n </Tab>\n <Tab eventKey=\"roles\" title={intl.formatMessage(messages.rolesTab)}>\n <RolesContent />\n </Tab>\n </Tabs>\n </>\n );\n};\n\nexport default CourseTeamPage;\n"]}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useMemo } from 'react';
|
|
3
|
+
import { useParams } from 'react-router-dom';
|
|
4
|
+
import { useIntl } from '@openedx/frontend-base';
|
|
5
|
+
import { Button, DataTable, FormControl, Icon } from '@openedx/paragon';
|
|
6
|
+
import { FilterList } from '@openedx/paragon/icons';
|
|
7
|
+
import UsernameFilter from '../../components/UsernameFilter';
|
|
8
|
+
import { useRoles, useTeamMembers } from '../../courseTeam/data/apiHook';
|
|
9
|
+
import messages from '../../courseTeam/messages';
|
|
10
|
+
const TEAM_MEMBERS_PAGE_SIZE = 25;
|
|
11
|
+
const RoleFilter = ({ column: { filterValue, setFilter } }) => {
|
|
12
|
+
const intl = useIntl();
|
|
13
|
+
const { courseId = '' } = useParams();
|
|
14
|
+
const { data } = useRoles(courseId);
|
|
15
|
+
const handleSelectChange = (e) => {
|
|
16
|
+
setFilter(e.target.value);
|
|
17
|
+
};
|
|
18
|
+
const roles = useMemo(() => {
|
|
19
|
+
return [{ value: '', label: intl.formatMessage(messages.allRoles) }, ...((data === null || data === void 0 ? void 0 : data.results) || []).map((role) => ({ value: role.role, label: role.displayName }))];
|
|
20
|
+
}, [data, intl]);
|
|
21
|
+
return (_jsx(FormControl, { as: "select", className: "mb-0", disabled: !data, name: "role", size: "md", value: filterValue, onChange: handleSelectChange, leadingElement: _jsx(Icon, { src: FilterList }), children: roles.map(role => (_jsx("option", { value: role.value, children: role.label }, role.value))) }));
|
|
22
|
+
};
|
|
23
|
+
const MembersContent = () => {
|
|
24
|
+
const intl = useIntl();
|
|
25
|
+
const { courseId = '' } = useParams();
|
|
26
|
+
const [filters, setFilters] = useState({ page: 0, emailOrUsername: '', role: '' });
|
|
27
|
+
const { data: { results: teamMembers = [], numPages = 1, count = 0 } = {}, isLoading = false } = useTeamMembers(courseId, Object.assign(Object.assign({}, filters), { pageSize: TEAM_MEMBERS_PAGE_SIZE }));
|
|
28
|
+
const tableColumns = useMemo(() => [
|
|
29
|
+
{ accessor: 'username', Header: intl.formatMessage(messages.username), Filter: UsernameFilter },
|
|
30
|
+
{ accessor: 'email', Header: intl.formatMessage(messages.email), disableFilters: true },
|
|
31
|
+
{ accessor: 'role', Header: intl.formatMessage(messages.role), Filter: RoleFilter },
|
|
32
|
+
], [intl]);
|
|
33
|
+
const additionalColumns = useMemo(() => [{
|
|
34
|
+
id: 'actions',
|
|
35
|
+
Header: intl.formatMessage(messages.actions),
|
|
36
|
+
Cell: () => (_jsx(Button, { variant: "link", size: "inline", children: intl.formatMessage(messages.edit) }))
|
|
37
|
+
}], [intl]);
|
|
38
|
+
const handleFetchData = (data) => {
|
|
39
|
+
var _a, _b;
|
|
40
|
+
const usernameFilter = (_a = data.filters) === null || _a === void 0 ? void 0 : _a.find((f) => f.id === 'username');
|
|
41
|
+
const newEmailOrUsername = usernameFilter ? usernameFilter.value : '';
|
|
42
|
+
const rolesFilter = (_b = data.filters) === null || _b === void 0 ? void 0 : _b.find((f) => f.id === 'role');
|
|
43
|
+
const newRole = rolesFilter ? rolesFilter.value : '';
|
|
44
|
+
const filtersChanged = (newEmailOrUsername !== filters.emailOrUsername) || (newRole !== filters.role);
|
|
45
|
+
if (filtersChanged) {
|
|
46
|
+
setFilters((prevFilters) => (Object.assign(Object.assign({}, prevFilters), { emailOrUsername: newEmailOrUsername, role: newRole, page: 0 })));
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (data.pageIndex !== filters.page) {
|
|
50
|
+
setFilters((prevFilters) => (Object.assign(Object.assign({}, prevFilters), { page: data.pageIndex })));
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
const tableState = useMemo(() => ({
|
|
54
|
+
pageIndex: filters.page,
|
|
55
|
+
pageSize: TEAM_MEMBERS_PAGE_SIZE,
|
|
56
|
+
}), [filters.page]);
|
|
57
|
+
return (_jsxs(DataTable, { additionalColumns: additionalColumns, columns: tableColumns, data: teamMembers, fetchData: handleFetchData, state: tableState, isFilterable: true, isLoading: isLoading, isPaginated: true, itemCount: count, manualFilters: true, manualPagination: true, numBreakoutFilters: 2, pageSize: TEAM_MEMBERS_PAGE_SIZE, pageCount: numPages, RowStatusComponent: () => null, children: [_jsx(DataTable.TableControlBar, {}), _jsx(DataTable.Table, {}), _jsx(DataTable.EmptyTable, { content: intl.formatMessage(messages.noTeamMembers) }), _jsx(DataTable.TableFooter, {})] }));
|
|
58
|
+
};
|
|
59
|
+
export default MembersContent;
|
|
60
|
+
//# sourceMappingURL=MembersContent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MembersContent.js","sourceRoot":"","sources":["../../../src/courseTeam/components/MembersContent.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState, useMemo } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useIntl } from '@openedx/frontend-base';\nimport { Button, DataTable, FormControl, Icon } from '@openedx/paragon';\nimport { FilterList } from '@openedx/paragon/icons';\nimport UsernameFilter from '@src/components/UsernameFilter';\nimport { useRoles, useTeamMembers } from '@src/courseTeam/data/apiHook';\nimport messages from '@src/courseTeam/messages';\nimport { Role } from '@src/courseTeam/types';\nimport { DataTableFetchDataProps } from '@src/types';\n\nconst TEAM_MEMBERS_PAGE_SIZE = 25;\n\nconst RoleFilter = ({ column: { filterValue, setFilter } }: { column: { filterValue: string, setFilter: (value: string) => void } }) => {\n const intl = useIntl();\n const { courseId = '' } = useParams<{ courseId: string }>();\n const { data } = useRoles(courseId);\n\n const handleSelectChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\n setFilter(e.target.value);\n };\n\n const roles = useMemo(() => {\n return [{ value: '', label: intl.formatMessage(messages.allRoles) }, ...(data?.results || []).map((role: Role) => ({ value: role.role, label: role.displayName }))];\n }, [data, intl]);\n\n return (\n <FormControl\n as=\"select\"\n className=\"mb-0\"\n disabled={!data}\n name=\"role\"\n size=\"md\"\n value={filterValue}\n onChange={handleSelectChange}\n leadingElement={<Icon src={FilterList} />}\n >\n {roles.map(role => (\n <option key={role.value} value={role.value}>\n {role.label}\n </option>\n ))}\n </FormControl>\n );\n};\n\nconst MembersContent = () => {\n const intl = useIntl();\n const { courseId = '' } = useParams<{ courseId: string }>();\n const [filters, setFilters] = useState({ page: 0, emailOrUsername: '', role: '' });\n const { data: { results: teamMembers = [], numPages = 1, count = 0 } = {}, isLoading = false } = useTeamMembers(courseId, { ...filters, pageSize: TEAM_MEMBERS_PAGE_SIZE });\n\n const tableColumns = useMemo(() => [\n { accessor: 'username', Header: intl.formatMessage(messages.username), Filter: UsernameFilter },\n { accessor: 'email', Header: intl.formatMessage(messages.email), disableFilters: true },\n { accessor: 'role', Header: intl.formatMessage(messages.role), Filter: RoleFilter },\n ], [intl]);\n\n const additionalColumns = useMemo(() => [{\n id: 'actions',\n Header: intl.formatMessage(messages.actions),\n Cell: () => (\n <Button variant=\"link\" size=\"inline\">\n {intl.formatMessage(messages.edit)}\n </Button>\n )\n }], [intl]);\n\n const handleFetchData = (data: DataTableFetchDataProps) => {\n const usernameFilter = data.filters?.find((f) => f.id === 'username');\n const newEmailOrUsername = usernameFilter ? usernameFilter.value : '';\n const rolesFilter = data.filters?.find((f) => f.id === 'role');\n const newRole = rolesFilter ? rolesFilter.value : '';\n const filtersChanged = (newEmailOrUsername !== filters.emailOrUsername) || (newRole !== filters.role);\n\n if (filtersChanged) {\n setFilters((prevFilters) => ({\n ...prevFilters,\n emailOrUsername: newEmailOrUsername,\n role: newRole,\n page: 0,\n }));\n return;\n }\n\n if (data.pageIndex !== filters.page) {\n setFilters((prevFilters) => ({ ...prevFilters, page: data.pageIndex }));\n }\n };\n\n const tableState = useMemo(() => ({\n pageIndex: filters.page,\n pageSize: TEAM_MEMBERS_PAGE_SIZE,\n }), [filters.page]);\n\n return (\n <DataTable\n additionalColumns={additionalColumns}\n columns={tableColumns}\n data={teamMembers}\n fetchData={handleFetchData}\n state={tableState}\n isFilterable\n isLoading={isLoading}\n isPaginated\n itemCount={count}\n manualFilters\n manualPagination\n numBreakoutFilters={2}\n pageSize={TEAM_MEMBERS_PAGE_SIZE}\n pageCount={numPages}\n RowStatusComponent={() => null}\n >\n <DataTable.TableControlBar />\n <DataTable.Table />\n <DataTable.EmptyTable content={intl.formatMessage(messages.noTeamMembers)} />\n <DataTable.TableFooter />\n </DataTable>\n );\n};\n\nexport default MembersContent;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RolesContent.js","sourceRoot":"","sources":["../../../src/courseTeam/components/RolesContent.tsx"],"names":[],"mappings":";AAAA,MAAM,YAAY,GAAG,GAAG,EAAE;IACxB,OAAO,CACL,cAAK,SAAS,EAAC,MAAM,yCAEf,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,YAAY,CAAC","sourcesContent":["const RolesContent = () => {\n return (\n <div className=\"mt-4\">\n Roles content goes here.\n </div>\n );\n};\n\nexport default RolesContent;\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { DataList } from '../../types';
|
|
2
|
+
import { CourseTeamMember, CourseTeamMemberQueryParams, Role } from '../../courseTeam/types';
|
|
3
|
+
export declare const getTeamMembers: (courseId: string, params: CourseTeamMemberQueryParams) => Promise<DataList<CourseTeamMember>>;
|
|
4
|
+
export declare const getRoles: (courseId: string) => Promise<Omit<DataList<Role>, "numPages" | "count">>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { camelCaseObject, getAuthenticatedHttpClient } from '@openedx/frontend-base';
|
|
11
|
+
import { getApiBaseUrl } from '../../data/api';
|
|
12
|
+
export const getTeamMembers = (courseId, params) => __awaiter(void 0, void 0, void 0, function* () {
|
|
13
|
+
const queryParams = new URLSearchParams({
|
|
14
|
+
page: (params.page + 1).toString(),
|
|
15
|
+
page_size: params.pageSize.toString(),
|
|
16
|
+
});
|
|
17
|
+
if (params.emailOrUsername) {
|
|
18
|
+
queryParams.append('email_or_username', params.emailOrUsername);
|
|
19
|
+
}
|
|
20
|
+
if (params.role) {
|
|
21
|
+
queryParams.append('role', params.role);
|
|
22
|
+
}
|
|
23
|
+
const { data } = yield getAuthenticatedHttpClient().get(`${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/team?${queryParams.toString()}`);
|
|
24
|
+
return camelCaseObject(data);
|
|
25
|
+
});
|
|
26
|
+
export const getRoles = (courseId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
27
|
+
const { data } = yield getAuthenticatedHttpClient().get(`${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/team/roles`);
|
|
28
|
+
return camelCaseObject(data);
|
|
29
|
+
});
|
|
30
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/courseTeam/data/api.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,eAAe,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAI9C,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,QAAgB,EAChB,MAAmC,EACE,EAAE;IACvC,MAAM,WAAW,GAAG,IAAI,eAAe,CAAC;QACtC,IAAI,EAAE,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE;QAClC,SAAS,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE;KACtC,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;QAC3B,WAAW,CAAC,MAAM,CAAC,mBAAmB,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;IAClE,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,GAAG,CACrD,GAAG,aAAa,EAAE,8BAA8B,QAAQ,SAAS,WAAW,CAAC,QAAQ,EAAE,EAAE,CAC1F,CAAC;IACF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAA,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAO,QAAgB,EAAuD,EAAE;IACtG,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,GAAG,CACrD,GAAG,aAAa,EAAE,8BAA8B,QAAQ,aAAa,CACtE,CAAC;IACF,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAA,CAAC","sourcesContent":["import { camelCaseObject, getAuthenticatedHttpClient } from '@openedx/frontend-base';\nimport { getApiBaseUrl } from '@src/data/api';\nimport { DataList } from '@src/types';\nimport { CourseTeamMember, CourseTeamMemberQueryParams, Role } from '@src/courseTeam/types';\n\nexport const getTeamMembers = async (\n courseId: string,\n params: CourseTeamMemberQueryParams\n): Promise<DataList<CourseTeamMember>> => {\n const queryParams = new URLSearchParams({\n page: (params.page + 1).toString(),\n page_size: params.pageSize.toString(),\n });\n\n if (params.emailOrUsername) {\n queryParams.append('email_or_username', params.emailOrUsername);\n }\n\n if (params.role) {\n queryParams.append('role', params.role);\n }\n\n const { data } = await getAuthenticatedHttpClient().get(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/team?${queryParams.toString()}`\n );\n return camelCaseObject(data);\n};\n\nexport const getRoles = async (courseId: string): Promise<Omit<DataList<Role>, 'numPages' | 'count'>> => {\n const { data } = await getAuthenticatedHttpClient().get(\n `${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/team/roles`\n );\n return camelCaseObject(data);\n};\n"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { CourseTeamMemberQueryParams } from '../../courseTeam/types';
|
|
2
|
+
export declare const useTeamMembers: (courseId: string, params: CourseTeamMemberQueryParams) => import("@tanstack/react-query").UseQueryResult<import("../../types").DataList<import("../../courseTeam/types").CourseTeamMember>, Error>;
|
|
3
|
+
export declare const useRoles: (courseId: string) => import("@tanstack/react-query").UseQueryResult<Omit<import("../../types").DataList<import("../../courseTeam/types").Role>, "count" | "numPages">, Error>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { useQuery } from '@tanstack/react-query';
|
|
2
|
+
import { getRoles, getTeamMembers } from '../../courseTeam/data/api';
|
|
3
|
+
import { courseTeamQueryKeys } from '../../courseTeam/data/queryKeys';
|
|
4
|
+
export const useTeamMembers = (courseId, params) => (useQuery({
|
|
5
|
+
queryKey: courseTeamQueryKeys.byCoursePaginated(courseId, params),
|
|
6
|
+
queryFn: () => getTeamMembers(courseId, params),
|
|
7
|
+
enabled: !!courseId,
|
|
8
|
+
}));
|
|
9
|
+
export const useRoles = (courseId) => (useQuery({
|
|
10
|
+
queryKey: courseTeamQueryKeys.roles(courseId),
|
|
11
|
+
queryFn: () => getRoles(courseId),
|
|
12
|
+
enabled: !!courseId,
|
|
13
|
+
}));
|
|
14
|
+
//# sourceMappingURL=apiHook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiHook.js","sourceRoot":"","sources":["../../../src/courseTeam/data/apiHook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAGrE,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,QAAgB,EAAE,MAAmC,EAAE,EAAE,CAAC,CACvF,QAAQ,CAAC;IACP,QAAQ,EAAE,mBAAmB,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC;IACjE,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC/C,OAAO,EAAE,CAAC,CAAC,QAAQ;CACpB,CAAC,CACH,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,QAAgB,EAAE,EAAE,CAAC,CAC5C,QAAQ,CAAC;IACP,QAAQ,EAAE,mBAAmB,CAAC,KAAK,CAAC,QAAQ,CAAC;IAC7C,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;IACjC,OAAO,EAAE,CAAC,CAAC,QAAQ;CACpB,CAAC,CACH,CAAC","sourcesContent":["import { useQuery } from '@tanstack/react-query';\nimport { getRoles, getTeamMembers } from '@src/courseTeam/data/api';\nimport { courseTeamQueryKeys } from '@src/courseTeam/data/queryKeys';\nimport { CourseTeamMemberQueryParams } from '@src/courseTeam/types';\n\nexport const useTeamMembers = (courseId: string, params: CourseTeamMemberQueryParams) => (\n useQuery({\n queryKey: courseTeamQueryKeys.byCoursePaginated(courseId, params),\n queryFn: () => getTeamMembers(courseId, params),\n enabled: !!courseId,\n })\n);\n\nexport const useRoles = (courseId: string) => (\n useQuery({\n queryKey: courseTeamQueryKeys.roles(courseId),\n queryFn: () => getRoles(courseId),\n enabled: !!courseId,\n })\n);\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { CourseTeamMemberQueryParams } from '../../courseTeam/types';
|
|
2
|
+
export declare const courseTeamQueryKeys: {
|
|
3
|
+
all: readonly ["org.openedx.frontend.app.instructorDashboard", "courseTeam"];
|
|
4
|
+
byCourse: (courseId: string) => readonly ["org.openedx.frontend.app.instructorDashboard", "courseTeam", string];
|
|
5
|
+
byCoursePaginated: (courseId: string, params: CourseTeamMemberQueryParams) => readonly ["org.openedx.frontend.app.instructorDashboard", "courseTeam", string, number, number, string, string];
|
|
6
|
+
roles: (courseId: string) => readonly ["org.openedx.frontend.app.instructorDashboard", "courseTeam", string, "roles"];
|
|
7
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { appId } from '../../constants';
|
|
2
|
+
export const courseTeamQueryKeys = {
|
|
3
|
+
all: [appId, 'courseTeam'],
|
|
4
|
+
byCourse: (courseId) => [...courseTeamQueryKeys.all, courseId],
|
|
5
|
+
byCoursePaginated: (courseId, params) => [
|
|
6
|
+
...courseTeamQueryKeys.byCourse(courseId),
|
|
7
|
+
params.page,
|
|
8
|
+
params.pageSize,
|
|
9
|
+
params.emailOrUsername || '',
|
|
10
|
+
params.role || ''
|
|
11
|
+
],
|
|
12
|
+
roles: (courseId) => [...courseTeamQueryKeys.byCourse(courseId), 'roles'],
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=queryKeys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queryKeys.js","sourceRoot":"","sources":["../../../src/courseTeam/data/queryKeys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAGvC,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,GAAG,EAAE,CAAC,KAAK,EAAE,YAAY,CAAU;IACnC,QAAQ,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,CAAC,GAAG,mBAAmB,CAAC,GAAG,EAAE,QAAQ,CAAU;IAC/E,iBAAiB,EAAE,CACjB,QAAgB,EAChB,MAAmC,EACnC,EAAE,CAAC;QACH,GAAG,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACzC,MAAM,CAAC,IAAI;QACX,MAAM,CAAC,QAAQ;QACf,MAAM,CAAC,eAAe,IAAI,EAAE;QAC5B,MAAM,CAAC,IAAI,IAAI,EAAE;KACT;IACV,KAAK,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,CAAC,GAAG,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAU;CAC3F,CAAC","sourcesContent":["import { appId } from '@src/constants';\nimport { CourseTeamMemberQueryParams } from '@src/courseTeam/types';\n\nexport const courseTeamQueryKeys = {\n all: [appId, 'courseTeam'] as const,\n byCourse: (courseId: string) => [...courseTeamQueryKeys.all, courseId] as const,\n byCoursePaginated: (\n courseId: string,\n params: CourseTeamMemberQueryParams\n ) => [\n ...courseTeamQueryKeys.byCourse(courseId),\n params.page,\n params.pageSize,\n params.emailOrUsername || '',\n params.role || ''\n ] as const,\n roles: (courseId: string) => [...courseTeamQueryKeys.byCourse(courseId), 'roles'] as const,\n};\n"]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
declare const messages: {
|
|
2
|
+
courseTeamTitle: {
|
|
3
|
+
id: string;
|
|
4
|
+
defaultMessage: string;
|
|
5
|
+
description: string;
|
|
6
|
+
};
|
|
7
|
+
addTeamMember: {
|
|
8
|
+
id: string;
|
|
9
|
+
defaultMessage: string;
|
|
10
|
+
description: string;
|
|
11
|
+
};
|
|
12
|
+
membersTab: {
|
|
13
|
+
id: string;
|
|
14
|
+
defaultMessage: string;
|
|
15
|
+
description: string;
|
|
16
|
+
};
|
|
17
|
+
rolesTab: {
|
|
18
|
+
id: string;
|
|
19
|
+
defaultMessage: string;
|
|
20
|
+
description: string;
|
|
21
|
+
};
|
|
22
|
+
username: {
|
|
23
|
+
id: string;
|
|
24
|
+
defaultMessage: string;
|
|
25
|
+
description: string;
|
|
26
|
+
};
|
|
27
|
+
email: {
|
|
28
|
+
id: string;
|
|
29
|
+
defaultMessage: string;
|
|
30
|
+
description: string;
|
|
31
|
+
};
|
|
32
|
+
role: {
|
|
33
|
+
id: string;
|
|
34
|
+
defaultMessage: string;
|
|
35
|
+
description: string;
|
|
36
|
+
};
|
|
37
|
+
actions: {
|
|
38
|
+
id: string;
|
|
39
|
+
defaultMessage: string;
|
|
40
|
+
description: string;
|
|
41
|
+
};
|
|
42
|
+
edit: {
|
|
43
|
+
id: string;
|
|
44
|
+
defaultMessage: string;
|
|
45
|
+
description: string;
|
|
46
|
+
};
|
|
47
|
+
noTeamMembers: {
|
|
48
|
+
id: string;
|
|
49
|
+
defaultMessage: string;
|
|
50
|
+
description: string;
|
|
51
|
+
};
|
|
52
|
+
allRoles: {
|
|
53
|
+
id: string;
|
|
54
|
+
defaultMessage: string;
|
|
55
|
+
description: string;
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
export default messages;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { defineMessages } from '@openedx/frontend-base';
|
|
2
|
+
const messages = defineMessages({
|
|
3
|
+
courseTeamTitle: {
|
|
4
|
+
id: 'instruct.courseTeam.page.title',
|
|
5
|
+
defaultMessage: 'Course Team Management',
|
|
6
|
+
description: 'Title for the course team page',
|
|
7
|
+
},
|
|
8
|
+
addTeamMember: {
|
|
9
|
+
id: 'instruct.courseTeam.addTeamMember',
|
|
10
|
+
defaultMessage: 'Add Team Member',
|
|
11
|
+
description: 'Button label for adding a team member',
|
|
12
|
+
},
|
|
13
|
+
membersTab: {
|
|
14
|
+
id: 'instruct.courseTeam.membersTab',
|
|
15
|
+
defaultMessage: 'Members',
|
|
16
|
+
description: 'Tab title for course team members',
|
|
17
|
+
},
|
|
18
|
+
rolesTab: {
|
|
19
|
+
id: 'instruct.courseTeam.rolesTab',
|
|
20
|
+
defaultMessage: 'Roles',
|
|
21
|
+
description: 'Tab title for course team roles',
|
|
22
|
+
},
|
|
23
|
+
username: {
|
|
24
|
+
id: 'instruct.courseTeam.username',
|
|
25
|
+
defaultMessage: 'Username',
|
|
26
|
+
description: 'Column header for team member username',
|
|
27
|
+
},
|
|
28
|
+
email: {
|
|
29
|
+
id: 'instruct.courseTeam.email',
|
|
30
|
+
defaultMessage: 'Email',
|
|
31
|
+
description: 'Column header for team member email',
|
|
32
|
+
},
|
|
33
|
+
role: {
|
|
34
|
+
id: 'instruct.courseTeam.role',
|
|
35
|
+
defaultMessage: 'Role',
|
|
36
|
+
description: 'Column header for team member role',
|
|
37
|
+
},
|
|
38
|
+
actions: {
|
|
39
|
+
id: 'instruct.courseTeam.actions',
|
|
40
|
+
defaultMessage: 'Actions',
|
|
41
|
+
description: 'Column header for team member actions',
|
|
42
|
+
},
|
|
43
|
+
edit: {
|
|
44
|
+
id: 'instruct.courseTeam.edit',
|
|
45
|
+
defaultMessage: 'Edit',
|
|
46
|
+
description: 'Button label for editing a team member',
|
|
47
|
+
},
|
|
48
|
+
noTeamMembers: {
|
|
49
|
+
id: 'instruct.courseTeam.noTeamMembers',
|
|
50
|
+
defaultMessage: 'No team members found.',
|
|
51
|
+
description: 'Message displayed when there are no team members',
|
|
52
|
+
},
|
|
53
|
+
allRoles: {
|
|
54
|
+
id: 'instruct.courseTeam.allRoles',
|
|
55
|
+
defaultMessage: 'All Roles',
|
|
56
|
+
description: 'Option label for filtering by all roles',
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
export default messages;
|
|
60
|
+
//# sourceMappingURL=messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/courseTeam/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,QAAQ,GAAG,cAAc,CAAC;IAC9B,eAAe,EAAE;QACf,EAAE,EAAE,gCAAgC;QACpC,cAAc,EAAE,wBAAwB;QACxC,WAAW,EAAE,gCAAgC;KAC9C;IACD,aAAa,EAAE;QACb,EAAE,EAAE,mCAAmC;QACvC,cAAc,EAAE,iBAAiB;QACjC,WAAW,EAAE,uCAAuC;KACrD;IACD,UAAU,EAAE;QACV,EAAE,EAAE,gCAAgC;QACpC,cAAc,EAAE,SAAS;QACzB,WAAW,EAAE,mCAAmC;KACjD;IACD,QAAQ,EAAE;QACR,EAAE,EAAE,8BAA8B;QAClC,cAAc,EAAE,OAAO;QACvB,WAAW,EAAE,iCAAiC;KAC/C;IACD,QAAQ,EAAE;QACR,EAAE,EAAE,8BAA8B;QAClC,cAAc,EAAE,UAAU;QAC1B,WAAW,EAAE,wCAAwC;KACtD;IACD,KAAK,EAAE;QACL,EAAE,EAAE,2BAA2B;QAC/B,cAAc,EAAE,OAAO;QACvB,WAAW,EAAE,qCAAqC;KACnD;IACD,IAAI,EAAE;QACJ,EAAE,EAAE,0BAA0B;QAC9B,cAAc,EAAE,MAAM;QACtB,WAAW,EAAE,oCAAoC;KAClD;IACD,OAAO,EAAE;QACP,EAAE,EAAE,6BAA6B;QACjC,cAAc,EAAE,SAAS;QACzB,WAAW,EAAE,uCAAuC;KACrD;IACD,IAAI,EAAE;QACJ,EAAE,EAAE,0BAA0B;QAC9B,cAAc,EAAE,MAAM;QACtB,WAAW,EAAE,wCAAwC;KACtD;IACD,aAAa,EAAE;QACb,EAAE,EAAE,mCAAmC;QACvC,cAAc,EAAE,wBAAwB;QACxC,WAAW,EAAE,kDAAkD;KAChE;IACD,QAAQ,EAAE;QACR,EAAE,EAAE,8BAA8B;QAClC,cAAc,EAAE,WAAW;QAC3B,WAAW,EAAE,yCAAyC;KACvD;CACF,CAAC,CAAC;AAEH,eAAe,QAAQ,CAAC","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n courseTeamTitle: {\n id: 'instruct.courseTeam.page.title',\n defaultMessage: 'Course Team Management',\n description: 'Title for the course team page',\n },\n addTeamMember: {\n id: 'instruct.courseTeam.addTeamMember',\n defaultMessage: 'Add Team Member',\n description: 'Button label for adding a team member',\n },\n membersTab: {\n id: 'instruct.courseTeam.membersTab',\n defaultMessage: 'Members',\n description: 'Tab title for course team members',\n },\n rolesTab: {\n id: 'instruct.courseTeam.rolesTab',\n defaultMessage: 'Roles',\n description: 'Tab title for course team roles',\n },\n username: {\n id: 'instruct.courseTeam.username',\n defaultMessage: 'Username',\n description: 'Column header for team member username',\n },\n email: {\n id: 'instruct.courseTeam.email',\n defaultMessage: 'Email',\n description: 'Column header for team member email',\n },\n role: {\n id: 'instruct.courseTeam.role',\n defaultMessage: 'Role',\n description: 'Column header for team member role',\n },\n actions: {\n id: 'instruct.courseTeam.actions',\n defaultMessage: 'Actions',\n description: 'Column header for team member actions',\n },\n edit: {\n id: 'instruct.courseTeam.edit',\n defaultMessage: 'Edit',\n description: 'Button label for editing a team member',\n },\n noTeamMembers: {\n id: 'instruct.courseTeam.noTeamMembers',\n defaultMessage: 'No team members found.',\n description: 'Message displayed when there are no team members',\n },\n allRoles: {\n id: 'instruct.courseTeam.allRoles',\n defaultMessage: 'All Roles',\n description: 'Option label for filtering by all roles',\n },\n});\n\nexport default messages;\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface CourseTeamMember {
|
|
2
|
+
username: string;
|
|
3
|
+
email: string;
|
|
4
|
+
role: string;
|
|
5
|
+
}
|
|
6
|
+
export interface CourseTeamMemberQueryParams {
|
|
7
|
+
page: number;
|
|
8
|
+
pageSize: number;
|
|
9
|
+
emailOrUsername?: string;
|
|
10
|
+
role?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface Role {
|
|
13
|
+
role: string;
|
|
14
|
+
displayName: string;
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/courseTeam/types.ts"],"names":[],"mappings":"","sourcesContent":["export interface CourseTeamMember {\n username: string,\n email: string,\n role: string,\n}\n\nexport interface CourseTeamMemberQueryParams {\n page: number,\n pageSize: number,\n emailOrUsername?: string,\n role?: string,\n}\n\nexport interface Role {\n role: string,\n displayName: string,\n}\n"]}
|
package/dist/data/api.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CourseInfoResponse } from '../courseInfo/types';
|
|
2
2
|
import { SelectedLearner } from '../types';
|
|
3
|
-
export declare const getApiBaseUrl: () =>
|
|
3
|
+
export declare const getApiBaseUrl: () => string;
|
|
4
4
|
/**
|
|
5
5
|
* Get course settings.
|
|
6
6
|
* @param {string} courseId
|
package/dist/data/api.js
CHANGED
|
@@ -7,9 +7,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import { camelCaseObject,
|
|
11
|
-
|
|
12
|
-
export const getApiBaseUrl = () => getAppConfig(appId).LMS_BASE_URL;
|
|
10
|
+
import { camelCaseObject, getSiteConfig, getAuthenticatedHttpClient } from '@openedx/frontend-base';
|
|
11
|
+
export const getApiBaseUrl = () => getSiteConfig().lmsBaseUrl;
|
|
13
12
|
/**
|
|
14
13
|
* Get course settings.
|
|
15
14
|
* @param {string} courseId
|
package/dist/data/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/data/api.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/data/api.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAIpG,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,EAAE,CAAC,aAAa,EAAE,CAAC,UAAU,CAAC;AAE9D;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAO,QAAgB,EAA+B,EAAE;IACnF,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE;SAChD,GAAG,CAAC,GAAG,aAAa,EAAE,8BAA8B,QAAQ,EAAE,CAAC,CAAC;IACnE,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAA,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAO,QAAgB,EAAE,EAAE;;IAC1D,MAAM,QAAQ,GAAG,MAAM,0BAA0B,EAAE,CAAC,IAAI,CACtD,GAAG,aAAa,EAAE,YAAY,QAAQ,uCAAuC,CAC9E,CAAC;IACF,OAAO,MAAA,MAAA,QAAQ,CAAC,IAAI,0CAAE,KAAK,0CAAE,GAAG,CAAC,eAAe,CAAC,CAAC;AACpD,CAAC,CAAA,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAO,QAAgB,EAAE,eAAuB,EAA4B,EAAE;IACtG,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE;SAChD,GAAG,CAAC,GAAG,aAAa,EAAE,8BAA8B,QAAQ,aAAa,eAAe,EAAE,CAAC,CAAC;IAC/F,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAA,CAAC","sourcesContent":["import { camelCaseObject, getSiteConfig, getAuthenticatedHttpClient } from '@openedx/frontend-base';\nimport { CourseInfoResponse } from '@src/courseInfo/types';\nimport { SelectedLearner } from '@src/types';\n\nexport const getApiBaseUrl = () => getSiteConfig().lmsBaseUrl;\n\n/**\n * Get course settings.\n * @param {string} courseId\n * @returns {Promise<Object>}\n */\nexport const getCourseInfo = async (courseId: string): Promise<CourseInfoResponse> => {\n const { data } = await getAuthenticatedHttpClient()\n .get(`${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}`);\n return camelCaseObject(data);\n};\n\n/**\n * Fetch pending instructor tasks for a course.\n * @param {string} courseId\n * @returns {Promise<Array>}\n */\nexport const fetchPendingTasks = async (courseId: string) => {\n const response = await getAuthenticatedHttpClient().post<{ results: Record<string, any>[] }>(\n `${getApiBaseUrl()}/courses/${courseId}/instructor/api/list_instructor_tasks`\n );\n return response.data?.tasks?.map(camelCaseObject);\n};\n\n/**\n * Get learner information for a course.\n * @param {string} courseId\n * @param {string} emailOrUsername\n * @returns {Promise<SelectedLearner>}\n */\nexport const getLearner = async (courseId: string, emailOrUsername: string): Promise<SelectedLearner> => {\n const { data } = await getAuthenticatedHttpClient()\n .get(`${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/learners/${emailOrUsername}`);\n return camelCaseObject(data);\n};\n"]}
|
|
@@ -2,24 +2,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import { useParams } from 'react-router-dom';
|
|
4
4
|
import { useIntl } from '@openedx/frontend-base';
|
|
5
|
-
import { Button, DataTable
|
|
5
|
+
import { Button, DataTable } from '@openedx/paragon';
|
|
6
6
|
import messages from '../messages';
|
|
7
7
|
import { useDateExtensions } from '../data/apiHook';
|
|
8
|
-
import { Search } from '@openedx/paragon/icons';
|
|
9
8
|
import SelectGradedSubsection from './SelectGradedSubsection';
|
|
10
9
|
import { useDebouncedFilter } from '../../hooks/useDebouncedFilter';
|
|
10
|
+
import UsernameFilter from '../../components/UsernameFilter';
|
|
11
11
|
const DATE_EXTENSIONS_PAGE_SIZE = 25;
|
|
12
|
-
const UsernameFilter = ({ column: { filterValue, setFilter } }) => {
|
|
13
|
-
const intl = useIntl();
|
|
14
|
-
const { inputValue, handleChange } = useDebouncedFilter({
|
|
15
|
-
filterValue,
|
|
16
|
-
setFilter,
|
|
17
|
-
});
|
|
18
|
-
const handleInputChange = (e) => {
|
|
19
|
-
handleChange(e.target.value);
|
|
20
|
-
};
|
|
21
|
-
return (_jsx(FormControl, { className: "mb-0", onChange: handleInputChange, placeholder: intl.formatMessage(messages.searchLearnerPlaceholder), trailingElement: _jsx(Icon, { src: Search }), value: inputValue }));
|
|
22
|
-
};
|
|
23
12
|
const GradedSubsectionFilter = ({ column: { filterValue, setFilter } }) => {
|
|
24
13
|
const intl = useIntl();
|
|
25
14
|
const { inputValue, handleChange } = useDebouncedFilter({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DateExtensionsList.js","sourceRoot":"","sources":["../../../src/dateExtensions/components/DateExtensionsList.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useIntl } from '@openedx/frontend-base';\nimport { Button, DataTable, FormControl, Icon } from '@openedx/paragon';\nimport messages from '../messages';\nimport { LearnerDateExtension } from '../types';\nimport { useDateExtensions } from '../data/apiHook';\nimport { Search } from '@openedx/paragon/icons';\nimport SelectGradedSubsection from './SelectGradedSubsection';\nimport { useDebouncedFilter } from '../../hooks/useDebouncedFilter';\nimport { DataTableFetchDataProps } from '@src/types';\n\nconst DATE_EXTENSIONS_PAGE_SIZE = 25;\n\nexport interface DateExtensionListProps {\n onResetExtensions?: (user: LearnerDateExtension) => void,\n onClickAdd?: () => void,\n}\n\nconst UsernameFilter = ({ column: { filterValue, setFilter } }: { column: { filterValue: string, setFilter: (value: string) => void } }) => {\n const intl = useIntl();\n const { inputValue, handleChange } = useDebouncedFilter({\n filterValue,\n setFilter,\n });\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n handleChange(e.target.value);\n };\n\n return (\n <FormControl\n className=\"mb-0\"\n onChange={handleInputChange}\n placeholder={intl.formatMessage(messages.searchLearnerPlaceholder)}\n trailingElement={<Icon src={Search} />}\n value={inputValue}\n />\n );\n};\n\nconst GradedSubsectionFilter = ({ column: { filterValue, setFilter } }: { column: { filterValue: string, setFilter: (value: string) => void } }) => {\n const intl = useIntl();\n const { inputValue, handleChange } = useDebouncedFilter({\n filterValue,\n setFilter,\n });\n\n const handleSelectChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\n handleChange(e.target.value);\n };\n\n return (\n <SelectGradedSubsection\n placeholder={intl.formatMessage(messages.allGradedSubsections)}\n onChange={handleSelectChange}\n value={inputValue}\n />\n );\n};\n\nconst DateExtensionsList = ({\n onResetExtensions = () => {},\n onClickAdd = () => {},\n}: DateExtensionListProps) => {\n const intl = useIntl();\n const { courseId = '' } = useParams<{ courseId: string }>();\n const [filters, setFilters] = useState<{ page: number, emailOrUsername: string, blockId: string }>({\n page: 0,\n emailOrUsername: '',\n blockId: '',\n });\n\n const { data = { count: 0, results: [], numPages: 0 }, isLoading } = useDateExtensions(courseId ?? '', {\n blockId: filters.blockId,\n emailOrUsername: filters.emailOrUsername,\n page: filters.page,\n pageSize: DATE_EXTENSIONS_PAGE_SIZE,\n });\n\n const tableColumns = [\n { accessor: 'username',\n Header: intl.formatMessage(messages.username),\n Filter: UsernameFilter,\n },\n { accessor: 'fullName', Header: intl.formatMessage(messages.fullname), disableFilters: true, },\n { accessor: 'email', Header: intl.formatMessage(messages.email), disableFilters: true, },\n { accessor: 'unitTitle',\n Header: intl.formatMessage(messages.gradedSubsection),\n Filter: GradedSubsectionFilter,\n },\n {\n accessor: 'extendedDueDate',\n Header: intl.formatMessage(messages.extendedDueDate),\n Cell: ({ value }: { value: string }) => (\n intl.formatDate(value, { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', timeZone: 'UTC' })\n ),\n disableFilters: true,\n },\n ];\n\n const additionalColumns = [{\n id: 'reset',\n Header: intl.formatMessage(messages.reset),\n Cell: ({ row }: { row: { original: LearnerDateExtension } }) => (\n <Button\n variant=\"link\"\n size=\"inline\"\n onClick={() => onResetExtensions(row.original)}\n >\n {intl.formatMessage(messages.resetExtensions)}\n </Button>\n )\n }];\n\n const handleFetchData = (data: DataTableFetchDataProps) => {\n const emailOrUsernameFilter = data.filters.find((filter) => filter.id === 'username');\n const newEmailOrUsername = emailOrUsernameFilter ? emailOrUsernameFilter.value : '';\n const blockIdFilter = data.filters.find((filter) => filter.id === 'unitTitle');\n const newBlockId = blockIdFilter ? blockIdFilter.value : '';\n\n const filterChanged = newEmailOrUsername !== filters.emailOrUsername || newBlockId !== filters.blockId;\n const pageChanged = data.pageIndex !== filters.page;\n\n // If filters changed, reset to page 0\n if (filterChanged) {\n setFilters({ page: 0, emailOrUsername: newEmailOrUsername, blockId: newBlockId });\n } else if (pageChanged) {\n // If only page changed (filters didn't change), update page\n setFilters({ page: data.pageIndex, emailOrUsername: newEmailOrUsername, blockId: newBlockId });\n }\n };\n\n return (\n <DataTable\n columns={tableColumns}\n additionalColumns={additionalColumns}\n data={data.results}\n fetchData={handleFetchData}\n state={{\n pageIndex: filters.page,\n pageSize: DATE_EXTENSIONS_PAGE_SIZE,\n filters: [\n {\n id: 'username',\n value: filters.emailOrUsername,\n },\n {\n id: 'unitTitle',\n value: filters.blockId,\n }\n ]\n }}\n isFilterable\n numBreakoutFilters={2}\n isLoading={isLoading}\n isPaginated\n itemCount={data.count}\n manualFilters\n manualPagination\n pageSize={DATE_EXTENSIONS_PAGE_SIZE}\n pageCount={data.numPages}\n FilterStatusComponent={DataTable.RowStatus}\n >\n <div className=\"d-flex justify-content-between align-items-start pt-1 mx-3 mb-3\">\n <DataTable.TableControlBar />\n <Button className=\"mt-2.5\" onClick={onClickAdd}>+ {intl.formatMessage(messages.addIndividualExtension)}</Button>\n </div>\n <DataTable.Table />\n <DataTable.EmptyTable content={intl.formatMessage(messages.noDateExtensions)} />\n <DataTable.TableFooter />\n </DataTable>\n );\n};\n\nexport default DateExtensionsList;\n"]}
|
|
1
|
+
{"version":3,"file":"DateExtensionsList.js","sourceRoot":"","sources":["../../../src/dateExtensions/components/DateExtensionsList.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useIntl } from '@openedx/frontend-base';\nimport { Button, DataTable } from '@openedx/paragon';\nimport messages from '../messages';\nimport { LearnerDateExtension } from '../types';\nimport { useDateExtensions } from '../data/apiHook';\nimport SelectGradedSubsection from './SelectGradedSubsection';\nimport { useDebouncedFilter } from '../../hooks/useDebouncedFilter';\nimport { DataTableFetchDataProps } from '@src/types';\nimport UsernameFilter from '@src/components/UsernameFilter';\n\nconst DATE_EXTENSIONS_PAGE_SIZE = 25;\n\nexport interface DateExtensionListProps {\n onResetExtensions?: (user: LearnerDateExtension) => void,\n onClickAdd?: () => void,\n}\n\nconst GradedSubsectionFilter = ({ column: { filterValue, setFilter } }: { column: { filterValue: string, setFilter: (value: string) => void } }) => {\n const intl = useIntl();\n const { inputValue, handleChange } = useDebouncedFilter({\n filterValue,\n setFilter,\n });\n\n const handleSelectChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\n handleChange(e.target.value);\n };\n\n return (\n <SelectGradedSubsection\n placeholder={intl.formatMessage(messages.allGradedSubsections)}\n onChange={handleSelectChange}\n value={inputValue}\n />\n );\n};\n\nconst DateExtensionsList = ({\n onResetExtensions = () => {},\n onClickAdd = () => {},\n}: DateExtensionListProps) => {\n const intl = useIntl();\n const { courseId = '' } = useParams<{ courseId: string }>();\n const [filters, setFilters] = useState<{ page: number, emailOrUsername: string, blockId: string }>({\n page: 0,\n emailOrUsername: '',\n blockId: '',\n });\n\n const { data = { count: 0, results: [], numPages: 0 }, isLoading } = useDateExtensions(courseId ?? '', {\n blockId: filters.blockId,\n emailOrUsername: filters.emailOrUsername,\n page: filters.page,\n pageSize: DATE_EXTENSIONS_PAGE_SIZE,\n });\n\n const tableColumns = [\n { accessor: 'username',\n Header: intl.formatMessage(messages.username),\n Filter: UsernameFilter,\n },\n { accessor: 'fullName', Header: intl.formatMessage(messages.fullname), disableFilters: true, },\n { accessor: 'email', Header: intl.formatMessage(messages.email), disableFilters: true, },\n { accessor: 'unitTitle',\n Header: intl.formatMessage(messages.gradedSubsection),\n Filter: GradedSubsectionFilter,\n },\n {\n accessor: 'extendedDueDate',\n Header: intl.formatMessage(messages.extendedDueDate),\n Cell: ({ value }: { value: string }) => (\n intl.formatDate(value, { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', timeZone: 'UTC' })\n ),\n disableFilters: true,\n },\n ];\n\n const additionalColumns = [{\n id: 'reset',\n Header: intl.formatMessage(messages.reset),\n Cell: ({ row }: { row: { original: LearnerDateExtension } }) => (\n <Button\n variant=\"link\"\n size=\"inline\"\n onClick={() => onResetExtensions(row.original)}\n >\n {intl.formatMessage(messages.resetExtensions)}\n </Button>\n )\n }];\n\n const handleFetchData = (data: DataTableFetchDataProps) => {\n const emailOrUsernameFilter = data.filters.find((filter) => filter.id === 'username');\n const newEmailOrUsername = emailOrUsernameFilter ? emailOrUsernameFilter.value : '';\n const blockIdFilter = data.filters.find((filter) => filter.id === 'unitTitle');\n const newBlockId = blockIdFilter ? blockIdFilter.value : '';\n\n const filterChanged = newEmailOrUsername !== filters.emailOrUsername || newBlockId !== filters.blockId;\n const pageChanged = data.pageIndex !== filters.page;\n\n // If filters changed, reset to page 0\n if (filterChanged) {\n setFilters({ page: 0, emailOrUsername: newEmailOrUsername, blockId: newBlockId });\n } else if (pageChanged) {\n // If only page changed (filters didn't change), update page\n setFilters({ page: data.pageIndex, emailOrUsername: newEmailOrUsername, blockId: newBlockId });\n }\n };\n\n return (\n <DataTable\n columns={tableColumns}\n additionalColumns={additionalColumns}\n data={data.results}\n fetchData={handleFetchData}\n state={{\n pageIndex: filters.page,\n pageSize: DATE_EXTENSIONS_PAGE_SIZE,\n filters: [\n {\n id: 'username',\n value: filters.emailOrUsername,\n },\n {\n id: 'unitTitle',\n value: filters.blockId,\n }\n ]\n }}\n isFilterable\n numBreakoutFilters={2}\n isLoading={isLoading}\n isPaginated\n itemCount={data.count}\n manualFilters\n manualPagination\n pageSize={DATE_EXTENSIONS_PAGE_SIZE}\n pageCount={data.numPages}\n FilterStatusComponent={DataTable.RowStatus}\n >\n <div className=\"d-flex justify-content-between align-items-start pt-1 mx-3 mb-3\">\n <DataTable.TableControlBar />\n <Button className=\"mt-2.5\" onClick={onClickAdd}>+ {intl.formatMessage(messages.addIndividualExtension)}</Button>\n </div>\n <DataTable.Table />\n <DataTable.EmptyTable content={intl.formatMessage(messages.noDateExtensions)} />\n <DataTable.TableFooter />\n </DataTable>\n );\n};\n\nexport default DateExtensionsList;\n"]}
|
|
@@ -114,11 +114,6 @@ declare const messages: {
|
|
|
114
114
|
defaultMessage: string;
|
|
115
115
|
description: string;
|
|
116
116
|
};
|
|
117
|
-
searchLearnerPlaceholder: {
|
|
118
|
-
id: string;
|
|
119
|
-
defaultMessage: string;
|
|
120
|
-
description: string;
|
|
121
|
-
};
|
|
122
117
|
noDateExtensions: {
|
|
123
118
|
id: string;
|
|
124
119
|
defaultMessage: string;
|
|
@@ -115,11 +115,6 @@ const messages = defineMessages({
|
|
|
115
115
|
defaultMessage: 'All Graded Subsections',
|
|
116
116
|
description: 'Label for the all graded subsections option in filters',
|
|
117
117
|
},
|
|
118
|
-
searchLearnerPlaceholder: {
|
|
119
|
-
id: 'instruct.dateExtensions.page.filters.searchLearnerPlaceholder',
|
|
120
|
-
defaultMessage: 'Search for a Learner',
|
|
121
|
-
description: 'Placeholder text for the search learner input field',
|
|
122
|
-
},
|
|
123
118
|
noDateExtensions: {
|
|
124
119
|
id: 'instruct.dateExtensions.page.noDateExtensions',
|
|
125
120
|
defaultMessage: 'No results found',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/dateExtensions/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,QAAQ,GAAG,cAAc,CAAC;IAC9B,mBAAmB,EAAE;QACnB,EAAE,EAAE,oCAAoC;QACxC,cAAc,EAAE,4BAA4B;QAC5C,WAAW,EAAE,gCAAgC;KAC9C;IACD,sBAAsB,EAAE;QACtB,EAAE,EAAE,qDAAqD;QACzD,cAAc,EAAE,0BAA0B;QAC1C,WAAW,EAAE,qDAAqD;KACnE;IACD,QAAQ,EAAE;QACR,EAAE,EAAE,mDAAmD;QACvD,cAAc,EAAE,WAAW;QAC3B,WAAW,EAAE,6DAA6D;KAC3E;IACD,QAAQ,EAAE;QACR,EAAE,EAAE,mDAAmD;QACvD,cAAc,EAAE,WAAW;QAC3B,WAAW,EAAE,6DAA6D;KAC3E;IACD,KAAK,EAAE;QACL,EAAE,EAAE,gDAAgD;QACpD,cAAc,EAAE,OAAO;QACvB,WAAW,EAAE,yDAAyD;KACvE;IACD,gBAAgB,EAAE;QAChB,EAAE,EAAE,2DAA2D;QAC/D,cAAc,EAAE,mBAAmB;QACnC,WAAW,EAAE,qEAAqE;KACnF;IACD,eAAe,EAAE;QACf,EAAE,EAAE,0DAA0D;QAC9D,cAAc,EAAE,mBAAmB;QACnC,WAAW,EAAE,qEAAqE;KACnF;IACD,KAAK,EAAE;QACL,EAAE,EAAE,gDAAgD;QACpD,cAAc,EAAE,OAAO;QACvB,WAAW,EAAE,yDAAyD;KACvE;IACD,eAAe,EAAE;QACf,EAAE,EAAE,qDAAqD;QACzD,cAAc,EAAE,kBAAkB;QAClC,WAAW,EAAE,sDAAsD;KACpE;IACD,uBAAuB,EAAE;QACvB,EAAE,EAAE,4DAA4D;QAChE,cAAc,EAAE,kCAAkC;QAClD,WAAW,EAAE,yCAAyC;KACvD;IACD,wBAAwB,EAAE;QACxB,EAAE,EAAE,6DAA6D;QACjE,cAAc,EAAE,iMAAiM;QACjN,WAAW,EAAE,kEAAkE;KAChF;IACD,MAAM,EAAE;QACN,EAAE,EAAE,gDAAgD;QACpD,cAAc,EAAE,QAAQ;QACxB,WAAW,EAAE,gDAAgD;KAC9D;IACD,OAAO,EAAE;QACP,EAAE,EAAE,iDAAiD;QACrD,cAAc,EAAE,4BAA4B;QAC5C,WAAW,EAAE,iDAAiD;KAC/D;IACD,KAAK,EAAE;QACL,EAAE,EAAE,+CAA+C;QACnD,cAAc,EAAE,OAAO;QACvB,WAAW,EAAE,+CAA+C;KAC7D;IACD,0BAA0B,EAAE;QAC1B,EAAE,EAAE,0DAA0D;QAC9D,cAAc,EAAE,uDAAuD;QACvE,WAAW,EAAE,oEAAoE;KAClF;IACD,6BAA6B,EAAE;QAC7B,EAAE,EAAE,uEAAuE;QAC3E,cAAc,EAAE,mCAAmC;QACnD,WAAW,EAAE,uDAAuD;KACrE;IACD,YAAY,EAAE;QACZ,EAAE,EAAE,8EAA8E;QAClF,cAAc,EAAE,eAAe;QAC/B,WAAW,EAAE,oCAAoC;KAClD;IACD,qBAAqB,EAAE;QACrB,EAAE,EAAE,uFAAuF;QAC3F,cAAc,EAAE,yGAAyG;QACzH,WAAW,EAAE,0DAA0D;KACxE;IACD,eAAe,EAAE;QACf,EAAE,EAAE,iFAAiF;QACrF,cAAc,EAAE,kBAAkB;QAClC,WAAW,EAAE,wCAAwC;KACtD;IACD,aAAa,EAAE;QACb,EAAE,EAAE,+EAA+E;QACnF,cAAc,EAAE,gBAAgB;QAChC,WAAW,EAAE,oCAAoC;KAClD;IACD,kBAAkB,EAAE;QAClB,EAAE,EAAE,oFAAoF;QACxF,cAAc,EAAE,sBAAsB;QACtC,WAAW,EAAE,0CAA0C;KACxD;IACD,sBAAsB,EAAE;QACtB,EAAE,EAAE,wFAAwF;QAC5F,cAAc,EAAE,0BAA0B;QAC1C,WAAW,EAAE,8CAA8C;KAC5D;IACD,oBAAoB,EAAE;QACpB,EAAE,EAAE,2DAA2D;QAC/D,cAAc,EAAE,wBAAwB;QACxC,WAAW,EAAE,wDAAwD;KACtE;IACD,
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/dateExtensions/messages.ts"],"names":[],"mappings":"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","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n dateExtensionsTitle: {\n id: 'instruct.dateExtensions.page.title',\n defaultMessage: 'Viewing Granted Extensions',\n description: 'Title for date extensions page',\n },\n addIndividualExtension: {\n id: 'instruct.dateExtensions.page.addIndividualExtension',\n defaultMessage: 'Add Individual Extension',\n description: 'Button text for adding an individual date extension',\n },\n username: {\n id: 'instruct.dateExtensions.page.tableHeader.username',\n defaultMessage: 'User Name',\n description: 'Label for the user name column in the date extensions table',\n },\n fullname: {\n id: 'instruct.dateExtensions.page.tableHeader.fullname',\n defaultMessage: 'Full Name',\n description: 'Label for the full name column in the date extensions table',\n },\n email: {\n id: 'instruct.dateExtensions.page.tableHeader.email',\n defaultMessage: 'Email',\n description: 'Label for the email column in the date extensions table',\n },\n gradedSubsection: {\n id: 'instruct.dateExtensions.page.tableHeader.gradedSubsection',\n defaultMessage: 'Graded Subsection',\n description: 'Label for the graded subsection column in the date extensions table',\n },\n extendedDueDate: {\n id: 'instruct.dateExtensions.page.tableHeader.extendedDueDate',\n defaultMessage: 'Extended Due Date',\n description: 'Label for the extended due date column in the date extensions table',\n },\n reset: {\n id: 'instruct.dateExtensions.page.tableHeader.reset',\n defaultMessage: 'Reset',\n description: 'Label for the reset column in the date extensions table',\n },\n resetExtensions: {\n id: 'instruct.dateExtensions.page.button.resetExtensions',\n defaultMessage: 'Reset Extensions',\n description: 'Button text for resetting date extensions for a user',\n },\n resetConfirmationHeader: {\n id: 'instruct.dateExtensions.page.resetModal.confirmationHeader',\n defaultMessage: 'Reset extensions for {username}?',\n description: 'Header for the reset confirmation modal',\n },\n resetConfirmationMessage: {\n id: 'instruct.dateExtensions.page.resetModal.confirmationMessage',\n defaultMessage: 'Resetting a problem\\'s due date rescinds a due date extension for a student on a particular subsection. This will revert the due date for the student back to the problem\\'s original due date.',\n description: 'Confirmation message for resetting extensions in the reset modal',\n },\n cancel: {\n id: 'instruct.dateExtensions.page.resetModal.cancel',\n defaultMessage: 'Cancel',\n description: 'Label for the cancel button in the reset modal',\n },\n confirm: {\n id: 'instruct.dateExtensions.page.resetModal.confirm',\n defaultMessage: 'Reset Due Date for Student',\n description: 'Label for the confirm button in the reset modal',\n },\n close: {\n id: 'instruct.dateExtensions.page.resetModal.close',\n defaultMessage: 'Close',\n description: 'Label for the close button in the reset modal',\n },\n missingUserOrCourseIdError: {\n id: 'instruct.dateExtensions.page.error.missingUserOrCourseId',\n defaultMessage: 'Unable to reset extension: missing user or course ID.',\n description: 'Error message shown when user or course ID is missing during reset',\n },\n addIndividualDueDateExtension: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.title',\n defaultMessage: 'Add Individual Due Date Extension',\n description: 'Title for the add individual due date extension modal',\n },\n addExtension: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.addExtension',\n defaultMessage: 'Add Extension',\n description: 'Label for the add extension button',\n },\n extensionInstructions: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.extensionInstructions',\n defaultMessage: 'To grant an extension, select a student, graded subsection, and define the extension due date and time.',\n description: 'Instructions for adding an individual due date extension',\n },\n defineExtension: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.defineExtension',\n defaultMessage: 'Define Extension',\n description: 'Label for the define extension section',\n },\n extensionDate: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.extensionDate',\n defaultMessage: 'Extension Date',\n description: 'Label for the extension date field',\n },\n reasonForExtension: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.reasonForExtension',\n defaultMessage: 'Reason for Extension',\n description: 'Label for the reason for extension field',\n },\n selectGradedSubsection: {\n id: 'instruct.dateExtensions.page.addIndividualDueDateExtensionModal.selectGradedSubsection',\n defaultMessage: 'Select Graded Subsection',\n description: 'Label for the select graded subsection field',\n },\n allGradedSubsections: {\n id: 'instruct.dateExtensions.page.filters.allGradedSubsections',\n defaultMessage: 'All Graded Subsections',\n description: 'Label for the all graded subsections option in filters',\n },\n noDateExtensions: {\n id: 'instruct.dateExtensions.page.noDateExtensions',\n defaultMessage: 'No results found',\n description: 'Message shown when there are no date extensions to display in the table',\n },\n});\n\nexport default messages;\n"]}
|