@openedx/frontend-app-instructor-dashboard 1.0.0-alpha.4 → 1.0.0-alpha.6
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/Main.js +2 -17
- package/dist/Main.js.map +1 -1
- package/dist/app.js +0 -6
- package/dist/app.js.map +1 -1
- package/dist/components/SpecifyProblem.d.ts +2 -0
- package/dist/components/SpecifyProblem.js +6 -0
- package/dist/components/SpecifyProblem.js.map +1 -0
- package/dist/courseInfo/types.d.ts +2 -0
- package/dist/courseInfo/types.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 +38 -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 +53 -0
- package/dist/courseTeam/messages.js +55 -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/grading/GradingPage.js +11 -2
- package/dist/grading/GradingPage.js.map +1 -1
- package/dist/grading/components/GradingActionRow.d.ts +2 -0
- package/dist/grading/components/GradingActionRow.js +28 -0
- package/dist/grading/components/GradingActionRow.js.map +1 -0
- package/dist/grading/components/GradingConfigurationModal.d.ts +6 -0
- package/dist/grading/components/GradingConfigurationModal.js +14 -0
- package/dist/grading/components/GradingConfigurationModal.js.map +1 -0
- package/dist/grading/components/GradingLearnerContent.d.ts +6 -0
- package/dist/grading/components/GradingLearnerContent.js +12 -0
- package/dist/grading/components/GradingLearnerContent.js.map +1 -0
- package/dist/grading/data/api.d.ts +1 -0
- package/dist/grading/data/api.js +17 -0
- package/dist/grading/data/api.js.map +1 -0
- package/dist/grading/data/apiHook.d.ts +1 -0
- package/dist/grading/data/apiHook.js +9 -0
- package/dist/grading/data/apiHook.js.map +1 -0
- package/dist/grading/data/queryKeys.d.ts +5 -0
- package/dist/grading/data/queryKeys.js +7 -0
- package/dist/grading/data/queryKeys.js.map +1 -0
- package/dist/grading/messages.d.ts +63 -0
- package/dist/grading/messages.js +65 -0
- package/dist/grading/messages.js.map +1 -0
- package/dist/grading/types.d.ts +1 -0
- package/dist/grading/types.js +2 -0
- package/dist/grading/types.js.map +1 -0
- package/package.json +1 -2
- package/dist/providers/QueryProvider.d.ts +0 -6
- package/dist/providers/QueryProvider.js +0 -16
- package/dist/providers/QueryProvider.js.map +0 -1
- package/dist/providers.d.ts +0 -3
- package/dist/providers.js +0 -8
- package/dist/providers.js.map +0 -1
package/dist/Main.js
CHANGED
|
@@ -1,25 +1,10 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
2
|
-
import { lazy, Suspense } from 'react';
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
2
|
import { CurrentAppProvider } from '@openedx/frontend-base';
|
|
4
|
-
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
5
3
|
import { Outlet } from 'react-router-dom';
|
|
6
4
|
import { AlertProvider } from './providers/AlertProvider';
|
|
7
5
|
import { appId } from './constants';
|
|
8
6
|
import PageWrapper from './pageWrapper/PageWrapper';
|
|
9
7
|
import './app.scss';
|
|
10
|
-
|
|
11
|
-
* Use a dynamic import guarded by process.env.NODE_ENV so the consumer's
|
|
12
|
-
* webpack dead-code-eliminates this in production builds. webpackIgnore
|
|
13
|
-
* tells webpack not to resolve the module at build time in dev mode, and
|
|
14
|
-
* the .catch() gracefully handles the case where it is not installed.
|
|
15
|
-
*/
|
|
16
|
-
const loadDevtools = () => import(/* webpackIgnore: true */ '@tanstack/react-query-devtools')
|
|
17
|
-
.then((m) => ({ default: m.ReactQueryDevtools }))
|
|
18
|
-
.catch(() => ({ default: () => null }));
|
|
19
|
-
const ReactQueryDevtools = process.env.NODE_ENV === 'development'
|
|
20
|
-
? lazy(loadDevtools)
|
|
21
|
-
: null;
|
|
22
|
-
const queryClient = new QueryClient();
|
|
23
|
-
const Main = () => (_jsx(CurrentAppProvider, { appId: appId, children: _jsx(QueryClientProvider, { client: queryClient, children: _jsx(AlertProvider, { children: _jsxs("main", { className: "d-flex flex-column flex-grow-1", children: [_jsx(PageWrapper, { children: _jsx(Outlet, {}) }), ReactQueryDevtools && (_jsx(Suspense, { fallback: null, children: _jsx(ReactQueryDevtools, { initialIsOpen: false }) }))] }) }) }) }));
|
|
8
|
+
const Main = () => (_jsx(CurrentAppProvider, { appId: appId, children: _jsx(AlertProvider, { children: _jsx("main", { className: "d-flex flex-column flex-grow-1", children: _jsx(PageWrapper, { children: _jsx(Outlet, {}) }) }) }) }));
|
|
24
9
|
export default Main;
|
|
25
10
|
//# sourceMappingURL=Main.js.map
|
package/dist/Main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Main.js","sourceRoot":"","sources":["../src/Main.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"Main.js","sourceRoot":"","sources":["../src/Main.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,WAAW,MAAM,2BAA2B,CAAC;AAEpD,OAAO,YAAY,CAAC;AAEpB,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,CACjB,KAAC,kBAAkB,IAAC,KAAK,EAAE,KAAK,YAC9B,KAAC,aAAa,cACZ,eAAM,SAAS,EAAC,gCAAgC,YAC9C,KAAC,WAAW,cACV,KAAC,MAAM,KAAG,GACE,GACT,GACO,GACG,CACtB,CAAC;AAEF,eAAe,IAAI,CAAC","sourcesContent":["import { CurrentAppProvider } from '@openedx/frontend-base';\nimport { Outlet } from 'react-router-dom';\nimport { AlertProvider } from './providers/AlertProvider';\nimport { appId } from './constants';\nimport PageWrapper from './pageWrapper/PageWrapper';\n\nimport './app.scss';\n\nconst Main = () => (\n <CurrentAppProvider appId={appId}>\n <AlertProvider>\n <main className=\"d-flex flex-column flex-grow-1\">\n <PageWrapper>\n <Outlet />\n </PageWrapper>\n </main>\n </AlertProvider>\n </CurrentAppProvider>\n);\n\nexport default Main;\n"]}
|
package/dist/app.js
CHANGED
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
import { appId } from './constants';
|
|
2
2
|
import routes from './routes';
|
|
3
3
|
import slots from './slots';
|
|
4
|
-
import providers from './providers';
|
|
5
4
|
import provides from './provides';
|
|
6
5
|
const app = {
|
|
7
6
|
appId,
|
|
8
7
|
routes,
|
|
9
|
-
providers,
|
|
10
8
|
provides,
|
|
11
9
|
slots,
|
|
12
|
-
config: {
|
|
13
|
-
NODE_ENV: 'development',
|
|
14
|
-
LMS_BASE_URL: 'http://local.openedx.io:8000'
|
|
15
|
-
},
|
|
16
10
|
};
|
|
17
11
|
export default app;
|
|
18
12
|
//# sourceMappingURL=app.js.map
|
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,
|
|
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"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpecifyProblem.js","sourceRoot":"","sources":["../../src/components/SpecifyProblem.tsx"],"names":[],"mappings":";AAAA,MAAM,cAAc,GAAG,GAAG,EAAE;IAC1B,OAAO,4CAA0B,CAAC;AACpC,CAAC,CAAC;AAEF,eAAe,cAAc,CAAC","sourcesContent":["const SpecifyProblem = () => {\n return <div>Specify Problem</div>;\n};\n\nexport default SpecifyProblem;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/courseInfo/types.ts"],"names":[],"mappings":"","sourcesContent":["import { TabProps } from '@src/instructorNav/InstructorNav';\n\nexport interface CourseInfoResponse {\n courseId: string,\n displayName: string,\n courseNumber: string,\n courseRun: string,\n enrollmentCounts: EnrollmentCounts,\n start: string | null,\n end: string | null,\n tabs?: TabProps[],\n totalEnrollment: number,\n studioUrl: string,\n pacing: string,\n org?: string,\n numSections: number,\n hasStarted: boolean,\n hasEnded: boolean,\n enrollmentEnd: string | null,\n enrollmentStart: string | null,\n gradeCutoffs: string | null,\n staffCount: number,\n learnerCount: number,\n permissions: {\n admin: boolean,\n dataResearcher: boolean,\n [key: string]: boolean,\n },\n}\n\ninterface EnrollmentCounts extends Record<string, number> {\n total: number,\n}\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/courseInfo/types.ts"],"names":[],"mappings":"","sourcesContent":["import { TabProps } from '@src/instructorNav/InstructorNav';\n\nexport interface CourseInfoResponse {\n courseId: string,\n displayName: string,\n courseNumber: string,\n courseRun: string,\n enrollmentCounts: EnrollmentCounts,\n start: string | null,\n end: string | null,\n tabs?: TabProps[],\n totalEnrollment: number,\n studioUrl: string,\n pacing: string,\n org?: string,\n numSections: number,\n hasStarted: boolean,\n hasEnded: boolean,\n enrollmentEnd: string | null,\n enrollmentStart: string | null,\n gradeCutoffs: string | null,\n staffCount: number,\n learnerCount: number,\n permissions: {\n admin: boolean,\n dataResearcher: boolean,\n [key: string]: boolean,\n },\n gradebookUrl: string,\n studioGradingUrl?: string,\n}\n\ninterface EnrollmentCounts extends Record<string, number> {\n total: number,\n}\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,38 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useCallback, useMemo } from 'react';
|
|
3
|
+
import { useParams } from 'react-router-dom';
|
|
4
|
+
import { useIntl } from '@openedx/frontend-base';
|
|
5
|
+
import { Button, DataTable } from '@openedx/paragon';
|
|
6
|
+
import { useTeamMembers } from '../../courseTeam/data/apiHook';
|
|
7
|
+
import messages from '../../courseTeam/messages';
|
|
8
|
+
const TEAM_MEMBERS_PAGE_SIZE = 25;
|
|
9
|
+
const MembersContent = () => {
|
|
10
|
+
const intl = useIntl();
|
|
11
|
+
const { courseId = '' } = useParams();
|
|
12
|
+
const [filters, setFilters] = useState({ page: 0, emailOrUsername: '', role: '' });
|
|
13
|
+
const { data: { results: teamMembers = [], numPages = 1, count = 0 } = {}, isLoading = false } = useTeamMembers(courseId, Object.assign(Object.assign({}, filters), { pageSize: TEAM_MEMBERS_PAGE_SIZE }));
|
|
14
|
+
const tableColumns = useMemo(() => [
|
|
15
|
+
{ accessor: 'username', Header: intl.formatMessage(messages.username) },
|
|
16
|
+
{ accessor: 'email', Header: intl.formatMessage(messages.email) },
|
|
17
|
+
{ accessor: 'role', Header: intl.formatMessage(messages.role) },
|
|
18
|
+
], [intl]);
|
|
19
|
+
const additionalColumns = useMemo(() => [{
|
|
20
|
+
id: 'actions',
|
|
21
|
+
Header: intl.formatMessage(messages.actions),
|
|
22
|
+
Cell: () => (_jsx(Button, { variant: "link", size: "inline", children: intl.formatMessage(messages.edit) }))
|
|
23
|
+
}], [intl]);
|
|
24
|
+
const handleFetchData = useCallback(({ pageIndex, filters: tableFilters }) => {
|
|
25
|
+
// Filters will be handled in a future iteration, for now we will just update pagination
|
|
26
|
+
console.log(pageIndex, tableFilters);
|
|
27
|
+
if (pageIndex !== filters.page) {
|
|
28
|
+
setFilters(prevFilters => (Object.assign(Object.assign({}, prevFilters), { page: pageIndex })));
|
|
29
|
+
}
|
|
30
|
+
}, [filters.page]);
|
|
31
|
+
const tableState = useMemo(() => ({
|
|
32
|
+
pageIndex: filters.page,
|
|
33
|
+
pageSize: TEAM_MEMBERS_PAGE_SIZE,
|
|
34
|
+
}), [filters.page]);
|
|
35
|
+
return (_jsxs(DataTable, { additionalColumns: additionalColumns, columns: tableColumns, data: teamMembers, fetchData: handleFetchData, state: tableState, isLoading: isLoading, isPaginated: true, itemCount: count, manualFilters: true, manualPagination: true, 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, {})] }));
|
|
36
|
+
};
|
|
37
|
+
export default MembersContent;
|
|
38
|
+
//# sourceMappingURL=MembersContent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MembersContent.js","sourceRoot":"","sources":["../../../src/courseTeam/components/MembersContent.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,QAAQ,MAAM,0BAA0B,CAAC;AAEhD,MAAM,sBAAsB,GAAG,EAAE,CAAC;AAElC,MAAM,cAAc,GAAG,GAAG,EAAE;IAC1B,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,EAAE,QAAQ,GAAG,EAAE,EAAE,GAAG,SAAS,EAAwB,CAAC;IAC5D,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,eAAe,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IACnF,MAAM,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,WAAW,GAAG,EAAE,EAAE,QAAQ,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,EAAE,EAAE,SAAS,GAAG,KAAK,EAAE,GAAG,cAAc,CAAC,QAAQ,kCAAO,OAAO,KAAE,QAAQ,EAAE,sBAAsB,IAAG,CAAC;IAE5K,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QACjC,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;QACvE,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;QACjE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;KAChE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,MAAM,iBAAiB,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;YACvC,EAAE,EAAE,SAAS;YACb,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC;YAC5C,IAAI,EAAE,GAAG,EAAE,CAAC,CACV,KAAC,MAAM,IAAC,OAAO,EAAC,MAAM,EAAC,IAAI,EAAC,QAAQ,YACjC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,GAC3B,CACV;SACF,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEZ,MAAM,eAAe,GAAG,WAAW,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,EAAmE,EAAE,EAAE;QAC5I,wFAAwF;QACxF,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QACrC,IAAI,SAAS,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC;YAC/B,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC,iCACrB,WAAW,KACd,IAAI,EAAE,SAAS,IACf,CAAC,CAAC;QACN,CAAC;IACH,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAEnB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAChC,SAAS,EAAE,OAAO,CAAC,IAAI;QACvB,QAAQ,EAAE,sBAAsB;KACjC,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAEpB,OAAO,CACL,MAAC,SAAS,IACR,iBAAiB,EAAE,iBAAiB,EACpC,OAAO,EAAE,YAAY,EACrB,IAAI,EAAE,WAAW,EACjB,SAAS,EAAE,eAAe,EAC1B,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,SAAS,EACpB,WAAW,QACX,SAAS,EAAE,KAAK,EAChB,aAAa,QACb,gBAAgB,QAChB,QAAQ,EAAE,sBAAsB,EAChC,SAAS,EAAE,QAAQ,EACnB,kBAAkB,EAAE,GAAG,EAAE,CAAC,IAAI,aAE9B,KAAC,SAAS,CAAC,eAAe,KAAG,EAC7B,KAAC,SAAS,CAAC,KAAK,KAAG,EACnB,KAAC,SAAS,CAAC,UAAU,IAAC,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAI,EAC7E,KAAC,SAAS,CAAC,WAAW,KAAG,IACf,CACb,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,cAAc,CAAC","sourcesContent":["import { useState, useCallback, useMemo } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useIntl } from '@openedx/frontend-base';\nimport { Button, DataTable } from '@openedx/paragon';\nimport { useTeamMembers } from '@src/courseTeam/data/apiHook';\nimport messages from '@src/courseTeam/messages';\n\nconst TEAM_MEMBERS_PAGE_SIZE = 25;\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) },\n { accessor: 'email', Header: intl.formatMessage(messages.email) },\n { accessor: 'role', Header: intl.formatMessage(messages.role) },\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 = useCallback(({ pageIndex, filters: tableFilters }: { pageIndex: number, filters: { id: string, value: string }[] }) => {\n // Filters will be handled in a future iteration, for now we will just update pagination\n console.log(pageIndex, tableFilters);\n if (pageIndex !== filters.page) {\n setFilters(prevFilters => ({\n ...prevFilters,\n page: pageIndex,\n }));\n }\n }, [filters.page]);\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 isLoading={isLoading}\n isPaginated\n itemCount={count}\n manualFilters\n manualPagination\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,53 @@
|
|
|
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
|
+
};
|
|
53
|
+
export default messages;
|
|
@@ -0,0 +1,55 @@
|
|
|
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
|
+
});
|
|
54
|
+
export default messages;
|
|
55
|
+
//# 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;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});\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"]}
|
|
@@ -1,6 +1,15 @@
|
|
|
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 { useState } from 'react';
|
|
3
|
+
import { useIntl } from '@openedx/frontend-base';
|
|
4
|
+
import { Button, ButtonGroup, Card } from '@openedx/paragon';
|
|
5
|
+
import { PendingTasks } from '../components/PendingTasks';
|
|
6
|
+
import GradingActionRow from '../grading/components/GradingActionRow';
|
|
7
|
+
import GradingLearnerContent from '../grading/components/GradingLearnerContent';
|
|
8
|
+
import messages from '../grading/messages';
|
|
2
9
|
const GradingPage = () => {
|
|
3
|
-
|
|
10
|
+
const intl = useIntl();
|
|
11
|
+
const [selectedTools, setSelectedTools] = useState('single');
|
|
12
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "d-flex justify-content-between align-items-center", children: [_jsx("h3", { className: "text-primary-700 mb-0", children: intl.formatMessage(messages.pageTitle) }), _jsx(GradingActionRow, {})] }), _jsxs(Card, { className: "bg-light-200 p-4 mt-4.5", children: [_jsxs(ButtonGroup, { className: "d-block", children: [_jsx(Button, { onClick: () => setSelectedTools('single'), variant: selectedTools === 'single' ? 'primary' : 'outline-primary', children: intl.formatMessage(messages.singleLearner) }), _jsx(Button, { onClick: () => setSelectedTools('all'), variant: selectedTools === 'all' ? 'primary' : 'outline-primary', children: intl.formatMessage(messages.allLearners) })] }), _jsx(GradingLearnerContent, { toolType: selectedTools })] }), _jsx(PendingTasks, {})] }));
|
|
4
13
|
};
|
|
5
14
|
export default GradingPage;
|
|
6
15
|
//# sourceMappingURL=GradingPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GradingPage.js","sourceRoot":"","sources":["../../src/grading/GradingPage.tsx"],"names":[],"mappings":";AAAA,MAAM,WAAW,GAAG,GAAG,EAAE;IACvB,OAAO,CACL,
|
|
1
|
+
{"version":3,"file":"GradingPage.js","sourceRoot":"","sources":["../../src/grading/GradingPage.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,gBAAgB,MAAM,0CAA0C,CAAC;AACxE,OAAO,qBAAqB,MAAM,+CAA+C,CAAC;AAClF,OAAO,QAAQ,MAAM,uBAAuB,CAAC;AAG7C,MAAM,WAAW,GAAG,GAAG,EAAE;IACvB,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAmB,QAAQ,CAAC,CAAC;IAE/E,OAAO,CACL,8BACE,eAAK,SAAS,EAAC,mDAAmD,aAChE,aAAI,SAAS,EAAC,uBAAuB,YAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAM,EACnF,KAAC,gBAAgB,KAAG,IAChB,EACN,MAAC,IAAI,IAAC,SAAS,EAAC,yBAAyB,aACvC,MAAC,WAAW,IAAC,SAAS,EAAC,SAAS,aAC9B,KAAC,MAAM,IACL,OAAO,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,QAAQ,CAAC,EACzC,OAAO,EAAE,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB,YAElE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,GACpC,EACT,KAAC,MAAM,IACL,OAAO,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,EACtC,OAAO,EAAE,aAAa,KAAK,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB,YAE/D,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,WAAW,CAAC,GAClC,IACG,EACd,KAAC,qBAAqB,IAAC,QAAQ,EAAE,aAAa,GAAI,IAC7C,EACP,KAAC,YAAY,KAAG,IACf,CACJ,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,WAAW,CAAC","sourcesContent":["import { useState } from 'react';\nimport { useIntl } from '@openedx/frontend-base';\nimport { Button, ButtonGroup, Card } from '@openedx/paragon';\nimport { PendingTasks } from '@src/components/PendingTasks';\nimport GradingActionRow from '@src/grading/components/GradingActionRow';\nimport GradingLearnerContent from '@src/grading/components/GradingLearnerContent';\nimport messages from '@src/grading/messages';\nimport { GradingToolsType } from '@src/grading/types';\n\nconst GradingPage = () => {\n const intl = useIntl();\n const [selectedTools, setSelectedTools] = useState<GradingToolsType>('single');\n\n return (\n <>\n <div className=\"d-flex justify-content-between align-items-center\">\n <h3 className=\"text-primary-700 mb-0\">{intl.formatMessage(messages.pageTitle)}</h3>\n <GradingActionRow />\n </div>\n <Card className=\"bg-light-200 p-4 mt-4.5\">\n <ButtonGroup className=\"d-block\">\n <Button\n onClick={() => setSelectedTools('single')}\n variant={selectedTools === 'single' ? 'primary' : 'outline-primary'}\n >\n {intl.formatMessage(messages.singleLearner)}\n </Button>\n <Button\n onClick={() => setSelectedTools('all')}\n variant={selectedTools === 'all' ? 'primary' : 'outline-primary'}\n >\n {intl.formatMessage(messages.allLearners)}\n </Button>\n </ButtonGroup>\n <GradingLearnerContent toolType={selectedTools} />\n </Card>\n <PendingTasks />\n </>\n );\n};\n\nexport default GradingPage;\n"]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { useParams } from 'react-router-dom';
|
|
4
|
+
import { useIntl } from '@openedx/frontend-base';
|
|
5
|
+
import { useToggle, ActionRow, Button, IconButton, ModalPopup, Menu, MenuItem } from '@openedx/paragon';
|
|
6
|
+
import { TrendingUp, MoreVert, OpenInNew } from '@openedx/paragon/icons';
|
|
7
|
+
import { useCourseInfo } from '../../data/apiHook';
|
|
8
|
+
import GradingConfigurationModal from '../../grading/components/GradingConfigurationModal';
|
|
9
|
+
import messages from '../../grading/messages';
|
|
10
|
+
const GradingActionRow = () => {
|
|
11
|
+
const { courseId = '' } = useParams();
|
|
12
|
+
const intl = useIntl();
|
|
13
|
+
const { data = { gradebookUrl: '', studioGradingUrl: '' } } = useCourseInfo(courseId);
|
|
14
|
+
const [configurationMenuTarget, setConfigurationMenuTarget] = useState(null);
|
|
15
|
+
const [isOpenMenu, openMenu, closeMenu] = useToggle(false);
|
|
16
|
+
const [isOpenConfigModal, openConfigModal, closeConfigModal] = useToggle(false);
|
|
17
|
+
const handleConfigurationMenuClick = (event) => {
|
|
18
|
+
setConfigurationMenuTarget(event === null || event === void 0 ? void 0 : event.currentTarget);
|
|
19
|
+
openMenu();
|
|
20
|
+
};
|
|
21
|
+
const handleConfigModalOpen = () => {
|
|
22
|
+
openConfigModal();
|
|
23
|
+
closeMenu();
|
|
24
|
+
};
|
|
25
|
+
return (_jsxs(_Fragment, { children: [_jsxs(ActionRow, { children: [_jsx(Button, { as: "a", href: data.gradebookUrl, iconBefore: TrendingUp, variant: "outline-primary", children: intl.formatMessage(messages.viewGradebook) }), _jsx(IconButton, { alt: intl.formatMessage(messages.configurationAlt), className: "lead", iconAs: MoreVert, onClick: handleConfigurationMenuClick })] }), _jsx(ModalPopup, { positionRef: configurationMenuTarget, onClose: closeMenu, isOpen: isOpenMenu, children: _jsxs(Menu, { children: [_jsx(MenuItem, { onClick: handleConfigModalOpen, children: intl.formatMessage(messages.viewGradingConfiguration) }), _jsx(MenuItem, { iconAfter: OpenInNew, as: "a", href: data.studioGradingUrl, target: "_blank", children: intl.formatMessage(messages.viewCourseGradingSettings) })] }) }), _jsx(GradingConfigurationModal, { isOpen: isOpenConfigModal, onClose: closeConfigModal })] }));
|
|
26
|
+
};
|
|
27
|
+
export default GradingActionRow;
|
|
28
|
+
//# sourceMappingURL=GradingActionRow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GradingActionRow.js","sourceRoot":"","sources":["../../../src/grading/components/GradingActionRow.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACxG,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,yBAAyB,MAAM,mDAAmD,CAAC;AAC1F,OAAO,QAAQ,MAAM,uBAAuB,CAAC;AAE7C,MAAM,gBAAgB,GAAG,GAAG,EAAE;IAC5B,MAAM,EAAE,QAAQ,GAAG,EAAE,EAAE,GAAG,SAAS,EAAwB,CAAC;IAC5D,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,EAAE,IAAI,GAAG,EAAE,YAAY,EAAE,EAAE,EAAE,gBAAgB,EAAE,EAAE,EAAE,EAAE,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IACtF,MAAM,CAAC,uBAAuB,EAAE,0BAA0B,CAAC,GAAG,QAAQ,CAA2B,IAAI,CAAC,CAAC;IACvG,MAAM,CAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAC3D,MAAM,CAAC,iBAAiB,EAAE,eAAe,EAAE,gBAAgB,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAEhF,MAAM,4BAA4B,GAAG,CAAC,KAA0C,EAAE,EAAE;QAClF,0BAA0B,CAAC,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,aAAa,CAAC,CAAC;QACjD,QAAQ,EAAE,CAAC;IACb,CAAC,CAAC;IAEF,MAAM,qBAAqB,GAAG,GAAG,EAAE;QACjC,eAAe,EAAE,CAAC;QAClB,SAAS,EAAE,CAAC;IACd,CAAC,CAAC;IAEF,OAAO,CACL,8BACE,MAAC,SAAS,eACR,KAAC,MAAM,IAAC,EAAE,EAAC,GAAG,EAAC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,EAAC,iBAAiB,YAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAU,EAC/I,KAAC,UAAU,IACT,GAAG,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAClD,SAAS,EAAC,MAAM,EAChB,MAAM,EAAE,QAAQ,EAChB,OAAO,EAAE,4BAA4B,GACrC,IACQ,EACZ,KAAC,UAAU,IAAC,WAAW,EAAE,uBAAuB,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,YACtF,MAAC,IAAI,eACH,KAAC,QAAQ,IAAC,OAAO,EAAE,qBAAqB,YACrC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,wBAAwB,CAAC,GAC7C,EACX,KAAC,QAAQ,IAAC,SAAS,EAAE,SAAS,EAAE,EAAE,EAAC,GAAG,EAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,EAAE,MAAM,EAAC,QAAQ,YAChF,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,yBAAyB,CAAC,GAC9C,IACN,GACI,EACb,KAAC,yBAAyB,IAAC,MAAM,EAAE,iBAAiB,EAAE,OAAO,EAAE,gBAAgB,GAAI,IAClF,CACJ,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,gBAAgB,CAAC","sourcesContent":["import { useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { useIntl } from '@openedx/frontend-base';\nimport { useToggle, ActionRow, Button, IconButton, ModalPopup, Menu, MenuItem } from '@openedx/paragon';\nimport { TrendingUp, MoreVert, OpenInNew } from '@openedx/paragon/icons';\nimport { useCourseInfo } from '@src/data/apiHook';\nimport GradingConfigurationModal from '@src/grading/components/GradingConfigurationModal';\nimport messages from '@src/grading/messages';\n\nconst GradingActionRow = () => {\n const { courseId = '' } = useParams<{ courseId: string }>();\n const intl = useIntl();\n const { data = { gradebookUrl: '', studioGradingUrl: '' } } = useCourseInfo(courseId);\n const [configurationMenuTarget, setConfigurationMenuTarget] = useState<HTMLButtonElement | null>(null);\n const [isOpenMenu, openMenu, closeMenu] = useToggle(false);\n const [isOpenConfigModal, openConfigModal, closeConfigModal] = useToggle(false);\n\n const handleConfigurationMenuClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n setConfigurationMenuTarget(event?.currentTarget);\n openMenu();\n };\n\n const handleConfigModalOpen = () => {\n openConfigModal();\n closeMenu();\n };\n\n return (\n <>\n <ActionRow>\n <Button as=\"a\" href={data.gradebookUrl} iconBefore={TrendingUp} variant=\"outline-primary\">{intl.formatMessage(messages.viewGradebook)}</Button>\n <IconButton\n alt={intl.formatMessage(messages.configurationAlt)}\n className=\"lead\"\n iconAs={MoreVert}\n onClick={handleConfigurationMenuClick}\n />\n </ActionRow>\n <ModalPopup positionRef={configurationMenuTarget} onClose={closeMenu} isOpen={isOpenMenu}>\n <Menu>\n <MenuItem onClick={handleConfigModalOpen}>\n {intl.formatMessage(messages.viewGradingConfiguration)}\n </MenuItem>\n <MenuItem iconAfter={OpenInNew} as=\"a\" href={data.studioGradingUrl} target=\"_blank\">\n {intl.formatMessage(messages.viewCourseGradingSettings)}\n </MenuItem>\n </Menu>\n </ModalPopup>\n <GradingConfigurationModal isOpen={isOpenConfigModal} onClose={closeConfigModal} />\n </>\n );\n};\n\nexport default GradingActionRow;\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
interface GradingConfigurationModalProps {
|
|
2
|
+
isOpen: boolean;
|
|
3
|
+
onClose: () => void;
|
|
4
|
+
}
|
|
5
|
+
declare const GradingConfigurationModal: ({ isOpen, onClose }: GradingConfigurationModalProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export default GradingConfigurationModal;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useParams } from 'react-router-dom';
|
|
3
|
+
import { Button, ModalDialog } from '@openedx/paragon';
|
|
4
|
+
import { useIntl } from '@openedx/frontend-base';
|
|
5
|
+
import messages from '../../grading/messages';
|
|
6
|
+
import { useGradingConfiguration } from '../../grading/data/apiHook';
|
|
7
|
+
const GradingConfigurationModal = ({ isOpen, onClose }) => {
|
|
8
|
+
const intl = useIntl();
|
|
9
|
+
const { courseId = '' } = useParams();
|
|
10
|
+
const { data = null } = useGradingConfiguration(courseId);
|
|
11
|
+
return (_jsxs(ModalDialog, { title: intl.formatMessage(messages.gradingConfiguration), isOpen: isOpen, onClose: onClose, isOverflowVisible: false, children: [_jsx(ModalDialog.Header, { children: _jsx("h3", { children: intl.formatMessage(messages.gradingConfiguration) }) }), _jsx(ModalDialog.Body, { children: _jsx("p", { children: data !== null && data !== void 0 ? data : intl.formatMessage(messages.noGradingConfiguration) }) }), _jsx(ModalDialog.Footer, { children: _jsx(Button, { onClick: onClose, children: intl.formatMessage(messages.close) }) })] }));
|
|
12
|
+
};
|
|
13
|
+
export default GradingConfigurationModal;
|
|
14
|
+
//# sourceMappingURL=GradingConfigurationModal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GradingConfigurationModal.js","sourceRoot":"","sources":["../../../src/grading/components/GradingConfigurationModal.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,QAAQ,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAOpE,MAAM,yBAAyB,GAAG,CAAC,EAAE,MAAM,EAAE,OAAO,EAAkC,EAAE,EAAE;IACxF,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,EAAE,QAAQ,GAAG,EAAE,EAAE,GAAG,SAAS,EAAwB,CAAC;IAC5D,MAAM,EAAE,IAAI,GAAG,IAAI,EAAE,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IAE1D,OAAO,CACL,MAAC,WAAW,IAAC,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,KAAK,aAC/H,KAAC,WAAW,CAAC,MAAM,cACjB,uBAAK,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,oBAAoB,CAAC,GAAM,GACzC,EACrB,KAAC,WAAW,CAAC,IAAI,cACf,sBAAI,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,sBAAsB,CAAC,GAAK,GACnD,EACnB,KAAC,WAAW,CAAC,MAAM,cACjB,KAAC,MAAM,IAAC,OAAO,EAAE,OAAO,YAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAU,GACpD,IACT,CACf,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,yBAAyB,CAAC","sourcesContent":["import { useParams } from 'react-router-dom';\nimport { Button, ModalDialog } from '@openedx/paragon';\nimport { useIntl } from '@openedx/frontend-base';\nimport messages from '@src/grading/messages';\nimport { useGradingConfiguration } from '@src/grading/data/apiHook';\n\ninterface GradingConfigurationModalProps {\n isOpen: boolean,\n onClose: () => void,\n}\n\nconst GradingConfigurationModal = ({ isOpen, onClose }: GradingConfigurationModalProps) => {\n const intl = useIntl();\n const { courseId = '' } = useParams<{ courseId: string }>();\n const { data = null } = useGradingConfiguration(courseId);\n\n return (\n <ModalDialog title={intl.formatMessage(messages.gradingConfiguration)} isOpen={isOpen} onClose={onClose} isOverflowVisible={false}>\n <ModalDialog.Header>\n <h3>{intl.formatMessage(messages.gradingConfiguration)}</h3>\n </ModalDialog.Header>\n <ModalDialog.Body>\n <p>{data ?? intl.formatMessage(messages.noGradingConfiguration)}</p>\n </ModalDialog.Body>\n <ModalDialog.Footer>\n <Button onClick={onClose}>{intl.formatMessage(messages.close)}</Button>\n </ModalDialog.Footer>\n </ModalDialog>\n );\n};\n\nexport default GradingConfigurationModal;\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { GradingToolsType } from '../../grading/types';
|
|
2
|
+
interface GradingLearnerContentProps {
|
|
3
|
+
toolType: GradingToolsType;
|
|
4
|
+
}
|
|
5
|
+
declare const GradingLearnerContent: ({ toolType }: GradingLearnerContentProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export default GradingLearnerContent;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useIntl } from '@openedx/frontend-base';
|
|
3
|
+
import SpecifyProblem from '../../components/SpecifyProblem';
|
|
4
|
+
import messages from '../../grading/messages';
|
|
5
|
+
const GradingLearnerContent = ({ toolType }) => {
|
|
6
|
+
const intl = useIntl();
|
|
7
|
+
return (_jsxs(_Fragment, { children: [_jsx("p", { className: "x-small text-primary mt-3", children: toolType === 'single'
|
|
8
|
+
? intl.formatMessage(messages.descriptionSingleLearner)
|
|
9
|
+
: intl.formatMessage(messages.descriptionAllLearners) }), _jsx(SpecifyProblem, {})] }));
|
|
10
|
+
};
|
|
11
|
+
export default GradingLearnerContent;
|
|
12
|
+
//# sourceMappingURL=GradingLearnerContent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GradingLearnerContent.js","sourceRoot":"","sources":["../../../src/grading/components/GradingLearnerContent.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,cAAc,MAAM,gCAAgC,CAAC;AAC5D,OAAO,QAAQ,MAAM,uBAAuB,CAAC;AAO7C,MAAM,qBAAqB,GAAG,CAAC,EAAE,QAAQ,EAA8B,EAAE,EAAE;IACzE,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IAEvB,OAAO,CACL,8BACE,YAAG,SAAS,EAAC,2BAA2B,YAEpC,QAAQ,KAAK,QAAQ;oBACnB,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,wBAAwB,CAAC;oBACvD,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,sBAAsB,CAAC,GAEvD,EACJ,KAAC,cAAc,KAAG,IACjB,CACJ,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,qBAAqB,CAAC","sourcesContent":["import { useIntl } from '@openedx/frontend-base';\nimport SpecifyProblem from '@src/components/SpecifyProblem';\nimport messages from '@src/grading/messages';\nimport { GradingToolsType } from '@src/grading/types';\n\ninterface GradingLearnerContentProps {\n toolType: GradingToolsType,\n}\n\nconst GradingLearnerContent = ({ toolType }: GradingLearnerContentProps) => {\n const intl = useIntl();\n\n return (\n <>\n <p className=\"x-small text-primary mt-3\">\n {\n toolType === 'single'\n ? intl.formatMessage(messages.descriptionSingleLearner)\n : intl.formatMessage(messages.descriptionAllLearners)\n }\n </p>\n <SpecifyProblem />\n </>\n );\n};\n\nexport default GradingLearnerContent;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const getGradingConfiguration: (courseId: string) => Promise<any>;
|
|
@@ -0,0 +1,17 @@
|
|
|
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 getGradingConfiguration = (courseId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
13
|
+
const { data } = yield getAuthenticatedHttpClient()
|
|
14
|
+
.get(`${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/grading-config`);
|
|
15
|
+
return camelCaseObject(data);
|
|
16
|
+
});
|
|
17
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/grading/data/api.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,eAAe,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAO,QAAgB,EAAE,EAAE;IAChE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE;SAChD,GAAG,CAAC,GAAG,aAAa,EAAE,8BAA8B,QAAQ,iBAAiB,CAAC,CAAC;IAClF,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';\n\nexport const getGradingConfiguration = async (courseId: string) => {\n const { data } = await getAuthenticatedHttpClient()\n .get(`${getApiBaseUrl()}/api/instructor/v2/courses/${courseId}/grading-config`);\n return camelCaseObject(data);\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useGradingConfiguration: (courseId: string) => import("@tanstack/react-query").UseQueryResult<any, Error>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { useQuery } from '@tanstack/react-query';
|
|
2
|
+
import { getGradingConfiguration } from '../../grading/data/api';
|
|
3
|
+
import { gradingQueryKeys } from '../../grading/data/queryKeys';
|
|
4
|
+
export const useGradingConfiguration = (courseId) => (useQuery({
|
|
5
|
+
queryKey: gradingQueryKeys.gradingConfiguration(courseId),
|
|
6
|
+
queryFn: () => getGradingConfiguration(courseId),
|
|
7
|
+
enabled: !!courseId,
|
|
8
|
+
}));
|
|
9
|
+
//# sourceMappingURL=apiHook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiHook.js","sourceRoot":"","sources":["../../../src/grading/data/apiHook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAE/D,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,QAAgB,EAAE,EAAE,CAAC,CAC3D,QAAQ,CAAC;IACP,QAAQ,EAAE,gBAAgB,CAAC,oBAAoB,CAAC,QAAQ,CAAC;IACzD,OAAO,EAAE,GAAG,EAAE,CAAC,uBAAuB,CAAC,QAAQ,CAAC;IAChD,OAAO,EAAE,CAAC,CAAC,QAAQ;CACpB,CAAC,CACH,CAAC","sourcesContent":["import { useQuery } from '@tanstack/react-query';\nimport { getGradingConfiguration } from '@src/grading/data/api';\nimport { gradingQueryKeys } from '@src/grading/data/queryKeys';\n\nexport const useGradingConfiguration = (courseId: string) => (\n useQuery({\n queryKey: gradingQueryKeys.gradingConfiguration(courseId),\n queryFn: () => getGradingConfiguration(courseId),\n enabled: !!courseId,\n })\n);\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const gradingQueryKeys: {
|
|
2
|
+
all: readonly ["org.openedx.frontend.app.instructorDashboard", "grading"];
|
|
3
|
+
byCourse: (courseId: string) => readonly ["org.openedx.frontend.app.instructorDashboard", "grading", string];
|
|
4
|
+
gradingConfiguration: (courseId: string) => readonly ["org.openedx.frontend.app.instructorDashboard", "grading", string, "gradingConfiguration"];
|
|
5
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { appId } from '../../constants';
|
|
2
|
+
export const gradingQueryKeys = {
|
|
3
|
+
all: [appId, 'grading'],
|
|
4
|
+
byCourse: (courseId) => [...gradingQueryKeys.all, courseId],
|
|
5
|
+
gradingConfiguration: (courseId) => [...gradingQueryKeys.byCourse(courseId), 'gradingConfiguration'],
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=queryKeys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queryKeys.js","sourceRoot":"","sources":["../../../src/grading/data/queryKeys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEvC,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,GAAG,EAAE,CAAC,KAAK,EAAE,SAAS,CAAU;IAChC,QAAQ,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,CAAC,GAAG,gBAAgB,CAAC,GAAG,EAAE,QAAQ,CAAU;IAC5E,oBAAoB,EAAE,CAAC,QAAgB,EAAE,EAAE,CAAC,CAAC,GAAG,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,sBAAsB,CAAU;CACtH,CAAC","sourcesContent":["import { appId } from '@src/constants';\n\nexport const gradingQueryKeys = {\n all: [appId, 'grading'] as const,\n byCourse: (courseId: string) => [...gradingQueryKeys.all, courseId] as const,\n gradingConfiguration: (courseId: string) => [...gradingQueryKeys.byCourse(courseId), 'gradingConfiguration'] as const,\n};\n"]}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
declare const messages: {
|
|
2
|
+
pageTitle: {
|
|
3
|
+
id: string;
|
|
4
|
+
defaultMessage: string;
|
|
5
|
+
description: string;
|
|
6
|
+
};
|
|
7
|
+
configurationAlt: {
|
|
8
|
+
id: string;
|
|
9
|
+
defaultMessage: string;
|
|
10
|
+
description: string;
|
|
11
|
+
};
|
|
12
|
+
viewGradebook: {
|
|
13
|
+
id: string;
|
|
14
|
+
defaultMessage: string;
|
|
15
|
+
description: string;
|
|
16
|
+
};
|
|
17
|
+
singleLearner: {
|
|
18
|
+
id: string;
|
|
19
|
+
defaultMessage: string;
|
|
20
|
+
description: string;
|
|
21
|
+
};
|
|
22
|
+
allLearners: {
|
|
23
|
+
id: string;
|
|
24
|
+
defaultMessage: string;
|
|
25
|
+
description: string;
|
|
26
|
+
};
|
|
27
|
+
descriptionSingleLearner: {
|
|
28
|
+
id: string;
|
|
29
|
+
defaultMessage: string;
|
|
30
|
+
description: string;
|
|
31
|
+
};
|
|
32
|
+
descriptionAllLearners: {
|
|
33
|
+
id: string;
|
|
34
|
+
defaultMessage: string;
|
|
35
|
+
description: string;
|
|
36
|
+
};
|
|
37
|
+
gradingConfiguration: {
|
|
38
|
+
id: string;
|
|
39
|
+
defaultMessage: string;
|
|
40
|
+
description: string;
|
|
41
|
+
};
|
|
42
|
+
close: {
|
|
43
|
+
id: string;
|
|
44
|
+
defaultMessage: string;
|
|
45
|
+
description: string;
|
|
46
|
+
};
|
|
47
|
+
viewGradingConfiguration: {
|
|
48
|
+
id: string;
|
|
49
|
+
defaultMessage: string;
|
|
50
|
+
description: string;
|
|
51
|
+
};
|
|
52
|
+
viewCourseGradingSettings: {
|
|
53
|
+
id: string;
|
|
54
|
+
defaultMessage: string;
|
|
55
|
+
description: string;
|
|
56
|
+
};
|
|
57
|
+
noGradingConfiguration: {
|
|
58
|
+
id: string;
|
|
59
|
+
defaultMessage: string;
|
|
60
|
+
description: string;
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
export default messages;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { defineMessages } from '@openedx/frontend-base';
|
|
2
|
+
const messages = defineMessages({
|
|
3
|
+
pageTitle: {
|
|
4
|
+
id: 'instruct.grading.pageTitle',
|
|
5
|
+
defaultMessage: 'Grading Tools',
|
|
6
|
+
description: 'Title for the grading page'
|
|
7
|
+
},
|
|
8
|
+
configurationAlt: {
|
|
9
|
+
id: 'instruct.grading.configurationAlt',
|
|
10
|
+
defaultMessage: 'Grading Configuration and Settings',
|
|
11
|
+
description: 'Alt text for the configuration icon button'
|
|
12
|
+
},
|
|
13
|
+
viewGradebook: {
|
|
14
|
+
id: 'instruct.grading.viewGradebook',
|
|
15
|
+
defaultMessage: 'View Gradebook',
|
|
16
|
+
description: 'Text for the button to view the gradebook'
|
|
17
|
+
},
|
|
18
|
+
singleLearner: {
|
|
19
|
+
id: 'instruct.grading.singleLearner',
|
|
20
|
+
defaultMessage: 'Single Learner',
|
|
21
|
+
description: 'Single Learner button label to display corresponding grading tools'
|
|
22
|
+
},
|
|
23
|
+
allLearners: {
|
|
24
|
+
id: 'instruct.grading.allLearners',
|
|
25
|
+
defaultMessage: 'All Learners',
|
|
26
|
+
description: 'All learners button label to display corresponding grading tools'
|
|
27
|
+
},
|
|
28
|
+
descriptionSingleLearner: {
|
|
29
|
+
id: 'instruct.grading.descriptionSingleLearner',
|
|
30
|
+
defaultMessage: 'These grading tools allow for grade review and adjustment for a specific learner on a specific problem.',
|
|
31
|
+
description: 'Description for single learner grading tools'
|
|
32
|
+
},
|
|
33
|
+
descriptionAllLearners: {
|
|
34
|
+
id: 'instruct.grading.descriptionAllLearners',
|
|
35
|
+
defaultMessage: 'These grading tools allow for grade review and adjustment all enrolled learners on a specific problem.',
|
|
36
|
+
description: 'Description for all learners grading tools'
|
|
37
|
+
},
|
|
38
|
+
gradingConfiguration: {
|
|
39
|
+
id: 'instruct.grading.gradingConfiguration',
|
|
40
|
+
defaultMessage: 'Grading Configuration',
|
|
41
|
+
description: 'Title for the grading configuration modal'
|
|
42
|
+
},
|
|
43
|
+
close: {
|
|
44
|
+
id: 'instruct.grading.modals.close',
|
|
45
|
+
defaultMessage: 'Close',
|
|
46
|
+
description: 'Text for the close button in the grading configuration modal'
|
|
47
|
+
},
|
|
48
|
+
viewGradingConfiguration: {
|
|
49
|
+
id: 'instruct.grading.viewGradingConfiguration',
|
|
50
|
+
defaultMessage: 'View Grading Configuration',
|
|
51
|
+
description: 'View grading configuration menu item label'
|
|
52
|
+
},
|
|
53
|
+
viewCourseGradingSettings: {
|
|
54
|
+
id: 'instruct.grading.viewCourseGradingSettings',
|
|
55
|
+
defaultMessage: 'View Course Grading Settings',
|
|
56
|
+
description: 'View course grading settings menu item label'
|
|
57
|
+
},
|
|
58
|
+
noGradingConfiguration: {
|
|
59
|
+
id: 'instruct.grading.noGradingConfiguration',
|
|
60
|
+
defaultMessage: 'No grading configuration found for this course.',
|
|
61
|
+
description: 'Message to display when there is no grading configuration for the course'
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
export default messages;
|
|
65
|
+
//# sourceMappingURL=messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/grading/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,QAAQ,GAAG,cAAc,CAAC;IAC9B,SAAS,EAAE;QACT,EAAE,EAAE,4BAA4B;QAChC,cAAc,EAAE,eAAe;QAC/B,WAAW,EAAE,4BAA4B;KAC1C;IACD,gBAAgB,EAAE;QAChB,EAAE,EAAE,mCAAmC;QACvC,cAAc,EAAE,oCAAoC;QACpD,WAAW,EAAE,4CAA4C;KAC1D;IACD,aAAa,EAAE;QACb,EAAE,EAAE,gCAAgC;QACpC,cAAc,EAAE,gBAAgB;QAChC,WAAW,EAAE,2CAA2C;KACzD;IACD,aAAa,EAAE;QACb,EAAE,EAAE,gCAAgC;QACpC,cAAc,EAAE,gBAAgB;QAChC,WAAW,EAAE,oEAAoE;KAClF;IACD,WAAW,EAAE;QACX,EAAE,EAAE,8BAA8B;QAClC,cAAc,EAAE,cAAc;QAC9B,WAAW,EAAE,kEAAkE;KAChF;IACD,wBAAwB,EAAE;QACxB,EAAE,EAAE,2CAA2C;QAC/C,cAAc,EAAE,yGAAyG;QACzH,WAAW,EAAE,8CAA8C;KAC5D;IACD,sBAAsB,EAAE;QACtB,EAAE,EAAE,yCAAyC;QAC7C,cAAc,EAAE,wGAAwG;QACxH,WAAW,EAAE,4CAA4C;KAC1D;IACD,oBAAoB,EAAE;QACpB,EAAE,EAAE,uCAAuC;QAC3C,cAAc,EAAE,uBAAuB;QACvC,WAAW,EAAE,2CAA2C;KACzD;IACD,KAAK,EAAE;QACL,EAAE,EAAE,+BAA+B;QACnC,cAAc,EAAE,OAAO;QACvB,WAAW,EAAE,8DAA8D;KAC5E;IACD,wBAAwB,EAAE;QACxB,EAAE,EAAE,2CAA2C;QAC/C,cAAc,EAAE,4BAA4B;QAC5C,WAAW,EAAE,4CAA4C;KAC1D;IACD,yBAAyB,EAAE;QACzB,EAAE,EAAE,4CAA4C;QAChD,cAAc,EAAE,8BAA8B;QAC9C,WAAW,EAAE,8CAA8C;KAC5D;IACD,sBAAsB,EAAE;QACtB,EAAE,EAAE,yCAAyC;QAC7C,cAAc,EAAE,iDAAiD;QACjE,WAAW,EAAE,0EAA0E;KACxF;CACF,CAAC,CAAC;AAEH,eAAe,QAAQ,CAAC","sourcesContent":["import { defineMessages } from '@openedx/frontend-base';\n\nconst messages = defineMessages({\n pageTitle: {\n id: 'instruct.grading.pageTitle',\n defaultMessage: 'Grading Tools',\n description: 'Title for the grading page'\n },\n configurationAlt: {\n id: 'instruct.grading.configurationAlt',\n defaultMessage: 'Grading Configuration and Settings',\n description: 'Alt text for the configuration icon button'\n },\n viewGradebook: {\n id: 'instruct.grading.viewGradebook',\n defaultMessage: 'View Gradebook',\n description: 'Text for the button to view the gradebook'\n },\n singleLearner: {\n id: 'instruct.grading.singleLearner',\n defaultMessage: 'Single Learner',\n description: 'Single Learner button label to display corresponding grading tools'\n },\n allLearners: {\n id: 'instruct.grading.allLearners',\n defaultMessage: 'All Learners',\n description: 'All learners button label to display corresponding grading tools'\n },\n descriptionSingleLearner: {\n id: 'instruct.grading.descriptionSingleLearner',\n defaultMessage: 'These grading tools allow for grade review and adjustment for a specific learner on a specific problem.',\n description: 'Description for single learner grading tools'\n },\n descriptionAllLearners: {\n id: 'instruct.grading.descriptionAllLearners',\n defaultMessage: 'These grading tools allow for grade review and adjustment all enrolled learners on a specific problem.',\n description: 'Description for all learners grading tools'\n },\n gradingConfiguration: {\n id: 'instruct.grading.gradingConfiguration',\n defaultMessage: 'Grading Configuration',\n description: 'Title for the grading configuration modal'\n },\n close: {\n id: 'instruct.grading.modals.close',\n defaultMessage: 'Close',\n description: 'Text for the close button in the grading configuration modal'\n },\n viewGradingConfiguration: {\n id: 'instruct.grading.viewGradingConfiguration',\n defaultMessage: 'View Grading Configuration',\n description: 'View grading configuration menu item label'\n },\n viewCourseGradingSettings: {\n id: 'instruct.grading.viewCourseGradingSettings',\n defaultMessage: 'View Course Grading Settings',\n description: 'View course grading settings menu item label'\n },\n noGradingConfiguration: {\n id: 'instruct.grading.noGradingConfiguration',\n defaultMessage: 'No grading configuration found for this course.',\n description: 'Message to display when there is no grading configuration for the course'\n }\n});\n\nexport default messages;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type GradingToolsType = 'single' | 'all';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/grading/types.ts"],"names":[],"mappings":"","sourcesContent":["export type GradingToolsType = 'single' | 'all';\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openedx/frontend-app-instructor-dashboard",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.6",
|
|
4
4
|
"description": "The Open edX Instructor Dashboard",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -62,7 +62,6 @@
|
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"@edx/browserslist-config": "^1.5.0",
|
|
65
|
-
"@tanstack/react-query-devtools": "^5.90.2",
|
|
66
65
|
"@testing-library/jest-dom": "^6.8.0",
|
|
67
66
|
"@testing-library/react": "^16.3.0",
|
|
68
67
|
"@testing-library/user-event": "^14.6.1",
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
3
|
-
const queryClient = new QueryClient({
|
|
4
|
-
defaultOptions: {
|
|
5
|
-
queries: {
|
|
6
|
-
staleTime: 5 * 60 * 1000, // 5 minutes
|
|
7
|
-
retry: 1,
|
|
8
|
-
refetchOnWindowFocus: false,
|
|
9
|
-
},
|
|
10
|
-
mutations: {
|
|
11
|
-
retry: 1,
|
|
12
|
-
},
|
|
13
|
-
},
|
|
14
|
-
});
|
|
15
|
-
export const QueryProvider = ({ children }) => (_jsx(QueryClientProvider, { client: queryClient, children: children }));
|
|
16
|
-
//# sourceMappingURL=QueryProvider.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"QueryProvider.js","sourceRoot":"","sources":["../../src/providers/QueryProvider.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAOzE,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC;IAClC,cAAc,EAAE;QACd,OAAO,EAAE;YACP,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,YAAY;YACtC,KAAK,EAAE,CAAC;YACR,oBAAoB,EAAE,KAAK;SAC5B;QACD,SAAS,EAAE;YACT,KAAK,EAAE,CAAC;SACT;KACF;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,EAAE,QAAQ,EAAsB,EAAE,EAAE,CAAC,CACjE,KAAC,mBAAmB,IAAC,MAAM,EAAE,WAAW,YACrC,QAAQ,GACW,CACvB,CAAC","sourcesContent":["import { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { ReactNode } from 'react';\n\ninterface QueryProviderProps {\n children: ReactNode,\n}\n\nconst queryClient = new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 5 * 60 * 1000, // 5 minutes\n retry: 1,\n refetchOnWindowFocus: false,\n },\n mutations: {\n retry: 1,\n },\n },\n});\n\nexport const QueryProvider = ({ children }: QueryProviderProps) => (\n <QueryClientProvider client={queryClient}>\n {children}\n </QueryClientProvider>\n);\n"]}
|
package/dist/providers.d.ts
DELETED
package/dist/providers.js
DELETED
package/dist/providers.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"providers.js","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,MAAM,SAAS,GAAkB;IAC/B,aAAa;IACb,aAAa;CACd,CAAC;AAEF,eAAe,SAAS,CAAC","sourcesContent":["import { AppProvider } from '@openedx/frontend-base';\nimport { QueryProvider } from './providers/QueryProvider';\nimport { AlertProvider } from './providers/AlertProvider';\n\nconst providers: AppProvider[] = [\n QueryProvider,\n AlertProvider,\n];\n\nexport default providers;\n"]}
|