@openedx/frontend-base 1.0.0-alpha.24 → 1.0.0-alpha.26
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/runtime/react/hooks/useActiveRouteRoleWatcher.js +4 -2
- package/dist/runtime/react/hooks/useActiveRouteRoleWatcher.js.map +1 -1
- package/dist/runtime/routing/utils.js +3 -3
- package/dist/runtime/routing/utils.js.map +1 -1
- package/dist/shell/Logo.js +3 -1
- package/dist/shell/Logo.js.map +1 -1
- package/dist/shell/constants.d.ts +1 -0
- package/dist/shell/constants.js +1 -0
- package/dist/shell/constants.js.map +1 -1
- package/dist/shell/dev/devHome/HomePage.js +2 -1
- package/dist/shell/dev/devHome/HomePage.js.map +1 -1
- package/dist/shell/dev/devHome/app.js +3 -2
- package/dist/shell/dev/devHome/app.js.map +1 -1
- package/dist/shell/dev/slotShowcase/SlotShowcasePage.js +1 -1
- package/dist/shell/dev/slotShowcase/SlotShowcasePage.js.map +1 -1
- package/dist/shell/header/AuthenticatedMenu.js +2 -4
- package/dist/shell/header/AuthenticatedMenu.js.map +1 -1
- package/dist/shell/header/Header.js +1 -1
- package/dist/shell/header/Header.js.map +1 -1
- package/dist/shell/header/app.d.ts +1 -0
- package/dist/shell/header/app.js +1 -0
- package/dist/shell/header/app.js.map +1 -1
- package/dist/shell/header/app.scss +10 -0
- package/dist/shell/header/desktop/DesktopLayout.js +2 -1
- package/dist/shell/header/desktop/DesktopLayout.js.map +1 -1
- package/dist/shell/header/desktop/PrimaryNavLinks.js +1 -1
- package/dist/shell/header/desktop/PrimaryNavLinks.js.map +1 -1
- package/dist/shell/header/mobile/MobileLayout.js +2 -2
- package/dist/shell/header/mobile/MobileLayout.js.map +1 -1
- package/dist/shell/index.d.ts +1 -1
- package/dist/shell/index.js +1 -1
- package/dist/shell/index.js.map +1 -1
- package/dist/shell/menus/LinkMenuItem.js +3 -1
- package/dist/shell/menus/LinkMenuItem.js.map +1 -1
- package/dist/shell/router/getAppRoutes.js +14 -1
- package/dist/shell/router/getAppRoutes.js.map +1 -1
- package/dist/shell/site.js +14 -3
- package/dist/shell/site.js.map +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/types.js.map +1 -1
- package/package.json +2 -1
|
@@ -11,8 +11,10 @@ const useActiveRouteRoleWatcher = () => {
|
|
|
11
11
|
// Route roles
|
|
12
12
|
for (const match of matches) {
|
|
13
13
|
if (isRoleRouteObject(match)) {
|
|
14
|
-
|
|
15
|
-
roles.
|
|
14
|
+
for (const role of match.handle.roles) {
|
|
15
|
+
if (!roles.includes(role)) {
|
|
16
|
+
roles.push(role);
|
|
17
|
+
}
|
|
16
18
|
}
|
|
17
19
|
}
|
|
18
20
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useActiveRouteRoleWatcher.js","sourceRoot":"","sources":["../../../../runtime/react/hooks/useActiveRouteRoleWatcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,MAAM,yBAAyB,GAAG,GAAG,EAAE;IACrC,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAE7B,2FAA2F;IAC3F,MAAM,oBAAoB,GAAG,WAAW,CAAC,GAAG,EAAE;QAC5C,uDAAuD;QACvD,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,cAAc;QACd,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC7B,IAAI,
|
|
1
|
+
{"version":3,"file":"useActiveRouteRoleWatcher.js","sourceRoot":"","sources":["../../../../runtime/react/hooks/useActiveRouteRoleWatcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,MAAM,yBAAyB,GAAG,GAAG,EAAE;IACrC,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAE7B,2FAA2F;IAC3F,MAAM,oBAAoB,GAAG,WAAW,CAAC,GAAG,EAAE;QAC5C,uDAAuD;QACvD,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,cAAc;QACd,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC7B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;oBACtC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;wBAC1B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACnB,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,SAAS,CAAC,GAAG,EAAE;QACb,mBAAmB,CAAC,oBAAoB,EAAE,CAAC,CAAC;IAC9C,CAAC,EAAE,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC;AACtC,CAAC,CAAC;AAEF,eAAe,yBAAyB,CAAC","sourcesContent":["import { useCallback, useEffect } from 'react';\nimport { useMatches } from 'react-router';\nimport { setActiveRouteRoles } from '../../config';\nimport { isRoleRouteObject } from '../../routing';\n\nconst useActiveRouteRoleWatcher = () => {\n const matches = useMatches();\n\n // We create this callback so we can use it right away to populate the default state value.\n const findActiveRouteRoles = useCallback(() => {\n // Starts with the widget roles and adds the others in.\n const roles: string[] = [];\n\n // Route roles\n for (const match of matches) {\n if (isRoleRouteObject(match)) {\n for (const role of match.handle.roles) {\n if (!roles.includes(role)) {\n roles.push(role);\n }\n }\n }\n }\n\n return roles;\n }, [matches]);\n\n useEffect(() => {\n setActiveRouteRoles(findActiveRouteRoles());\n }, [matches, findActiveRouteRoles]);\n};\n\nexport default useActiveRouteRoleWatcher;\n"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { getSiteConfig } from '../config';
|
|
2
2
|
function findRoleInRoutes(routes, role, prefix = '') {
|
|
3
|
-
var _a, _b;
|
|
3
|
+
var _a, _b, _c;
|
|
4
4
|
for (const route of routes) {
|
|
5
5
|
const segment = (_a = route.path) !== null && _a !== void 0 ? _a : '';
|
|
6
6
|
const fullPath = segment.startsWith('/') ? segment : `${prefix}/${segment}`.replace(/\/+/g, '/');
|
|
7
|
-
if (((_b = route.handle) === null || _b === void 0 ? void 0 : _b.
|
|
7
|
+
if ((_c = (_b = route.handle) === null || _b === void 0 ? void 0 : _b.roles) === null || _c === void 0 ? void 0 : _c.includes(role)) {
|
|
8
8
|
return fullPath || null;
|
|
9
9
|
}
|
|
10
10
|
if (Array.isArray(route.children)) {
|
|
@@ -38,6 +38,6 @@ export function getUrlByRouteRole(role) {
|
|
|
38
38
|
return null;
|
|
39
39
|
}
|
|
40
40
|
export function isRoleRouteObject(match) {
|
|
41
|
-
return match.handle !== undefined && '
|
|
41
|
+
return match.handle !== undefined && 'roles' in match.handle;
|
|
42
42
|
}
|
|
43
43
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../runtime/routing/utils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,SAAS,gBAAgB,CAAC,MAAqB,EAAE,IAAY,EAAE,MAAM,GAAG,EAAE;;IACxE,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,MAAA,KAAK,CAAC,IAAI,mCAAI,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAEjG,IAAI,
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../runtime/routing/utils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,SAAS,gBAAgB,CAAC,MAAqB,EAAE,IAAY,EAAE,MAAM,GAAG,EAAE;;IACxE,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,MAAA,KAAK,CAAC,IAAI,mCAAI,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAEjG,IAAI,MAAA,MAAA,KAAK,CAAC,MAAM,0CAAE,KAAK,0CAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACxC,OAAO,QAAQ,IAAI,IAAI,CAAC;QAC1B,CAAC;QAED,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClC,MAAM,KAAK,GAAG,gBAAgB,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;YAC/D,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACnB,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,aAAa,EAAE,CAAC;IAEjD,IAAI,IAAI,EAAE,CAAC;QACT,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC9B,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;gBACjD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;oBACnB,OAAO,KAAK,CAAC;gBACf,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,cAAc,EAAE,CAAC;QACnB,KAAK,MAAM,aAAa,IAAI,cAAc,EAAE,CAAC;YAC3C,IAAI,aAAa,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;gBAChC,OAAO,aAAa,CAAC,GAAG,CAAC;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAkB;IAClD,OAAO,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC;AAC/D,CAAC","sourcesContent":["import { RouteObject } from 'react-router';\n\nimport { RoleRouteObject } from '../../types';\nimport { getSiteConfig } from '../config';\n\nfunction findRoleInRoutes(routes: RouteObject[], role: string, prefix = ''): string | null {\n for (const route of routes) {\n const segment = route.path ?? '';\n const fullPath = segment.startsWith('/') ? segment : `${prefix}/${segment}`.replace(/\\/+/g, '/');\n\n if (route.handle?.roles?.includes(role)) {\n return fullPath || null;\n }\n\n if (Array.isArray(route.children)) {\n const found = findRoleInRoutes(route.children, role, fullPath);\n if (found !== null) {\n return found;\n }\n }\n }\n return null;\n}\n\nexport function getUrlByRouteRole(role: string) {\n const { apps, externalRoutes } = getSiteConfig();\n\n if (apps) {\n for (const app of apps) {\n if (Array.isArray(app.routes)) {\n const found = findRoleInRoutes(app.routes, role);\n if (found !== null) {\n return found;\n }\n }\n }\n }\n\n if (externalRoutes) {\n for (const externalRoute of externalRoutes) {\n if (externalRoute.role === role) {\n return externalRoute.url;\n }\n }\n }\n\n return null;\n}\n\nexport function isRoleRouteObject(match: RouteObject): match is RoleRouteObject {\n return match.handle !== undefined && 'roles' in match.handle;\n}\n"]}
|
package/dist/shell/Logo.js
CHANGED
|
@@ -2,9 +2,11 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { IntlProvider } from 'react-intl';
|
|
3
3
|
import { Hyperlink, Image } from '@openedx/paragon';
|
|
4
4
|
import { getSiteConfig } from '../runtime/config';
|
|
5
|
+
import { getUrlByRouteRole } from '../runtime/routing';
|
|
6
|
+
import { homeRole } from './constants';
|
|
5
7
|
export default function Logo(_a) {
|
|
6
8
|
var _b;
|
|
7
|
-
var { imageUrl = (_b = getSiteConfig().headerLogoImageUrl) !== null && _b !== void 0 ? _b : 'https://edx-cdn.org/v3/default/logo.svg', destinationUrl } = _a;
|
|
9
|
+
var { imageUrl = (_b = getSiteConfig().headerLogoImageUrl) !== null && _b !== void 0 ? _b : 'https://edx-cdn.org/v3/default/logo.svg', destinationUrl = getUrlByRouteRole(homeRole) || '/' } = _a;
|
|
8
10
|
const image = (_jsx(Image, { src: imageUrl, style: { maxHeight: '2rem' } }));
|
|
9
11
|
if (destinationUrl === undefined) {
|
|
10
12
|
return image;
|
package/dist/shell/Logo.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Logo.js","sourceRoot":"","sources":["../../shell/Logo.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"Logo.js","sourceRoot":"","sources":["../../shell/Logo.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAOvC,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,EAGjB;;QAHiB,EAC3B,QAAQ,GAAG,MAAA,aAAa,EAAE,CAAC,kBAAkB,mCAAI,yCAAyC,EAC1F,cAAc,GAAG,iBAAiB,CAAC,QAAQ,CAAC,IAAI,GAAG;IAEnD,MAAM,KAAK,GAAG,CACZ,KAAC,KAAK,IAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,GAAI,CACvD,CAAC;IAEF,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;QACjC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,CACL,KAAC,YAAY,IAAC,MAAM,EAAC,IAAI,YACvB,KAAC,SAAS,IAAC,WAAW,EAAE,cAAc,EAAE,SAAS,EAAC,KAAK,YACpD,KAAK,GACI,GACC,CAChB,CAAC;AACJ,CAAC","sourcesContent":["import { IntlProvider } from 'react-intl';\nimport { Hyperlink, Image } from '@openedx/paragon';\nimport { getSiteConfig } from '../runtime/config';\nimport { getUrlByRouteRole } from '../runtime/routing';\nimport { homeRole } from './constants';\n\ninterface LogoProps {\n imageUrl?: string,\n destinationUrl?: string,\n}\n\nexport default function Logo({\n imageUrl = getSiteConfig().headerLogoImageUrl ?? 'https://edx-cdn.org/v3/default/logo.svg',\n destinationUrl = getUrlByRouteRole(homeRole) || '/'\n}: LogoProps) {\n const image = (\n <Image src={imageUrl} style={{ maxHeight: '2rem' }} />\n );\n\n if (destinationUrl === undefined) {\n return image;\n }\n\n return (\n <IntlProvider locale=\"en\">\n <Hyperlink destination={destinationUrl} className=\"p-0\">\n {image}\n </Hyperlink>\n </IntlProvider>\n );\n}\n"]}
|
package/dist/shell/constants.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../shell/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,yBAAyB,GAAG,kDAAkD,CAAC","sourcesContent":["export const providesChromelessRolesId = 'org.openedx.frontend.provides.chromelessRoles.v1';\n"]}
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../shell/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG,gCAAgC,CAAC;AACzD,MAAM,CAAC,MAAM,yBAAyB,GAAG,kDAAkD,CAAC","sourcesContent":["export const homeRole = 'org.openedx.frontend.role.home';\nexport const providesChromelessRolesId = 'org.openedx.frontend.provides.chromelessRoles.v1';\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Container } from '@openedx/paragon';
|
|
2
3
|
import { Link } from 'react-router-dom';
|
|
3
4
|
import { useIntl } from '../../../runtime';
|
|
4
5
|
import { getUrlByRouteRole } from '../../../runtime/routing';
|
|
@@ -8,6 +9,6 @@ export default function HomePage() {
|
|
|
8
9
|
const dashboardUrl = getUrlByRouteRole('org.openedx.frontend.role.dashboard');
|
|
9
10
|
const slotShowcaseUrl = getUrlByRouteRole('org.openedx.frontend.role.slotShowcase');
|
|
10
11
|
const intl = useIntl();
|
|
11
|
-
return (_jsxs(
|
|
12
|
+
return (_jsxs(Container, { fluid: true, size: "xl", children: [_jsx("p", { children: intl.formatMessage(messages.homeContent) }), _jsxs("ul", { children: [coursewareUrl !== null && (_jsx("li", { children: _jsx(Link, { to: coursewareUrl, children: "Go to courseware page" }) })), dashboardUrl !== null && (_jsx("li", { children: _jsx(Link, { to: dashboardUrl, children: "Go to dashboard page" }) })), slotShowcaseUrl !== null && (_jsx("li", { children: _jsx(Link, { to: slotShowcaseUrl, children: "Go to slot showcase page" }) }))] })] }));
|
|
12
13
|
}
|
|
13
14
|
//# sourceMappingURL=HomePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HomePage.js","sourceRoot":"","sources":["../../../../shell/dev/devHome/HomePage.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,QAAQ,MAAM,YAAY,CAAC;AAElC,MAAM,CAAC,OAAO,UAAU,QAAQ;IAC9B,MAAM,aAAa,GAAG,iBAAiB,CAAC,sCAAsC,CAAC,CAAC;IAChF,MAAM,YAAY,GAAG,iBAAiB,CAAC,qCAAqC,CAAC,CAAC;IAC9E,MAAM,eAAe,GAAG,iBAAiB,CAAC,wCAAwC,CAAC,CAAC;IACpF,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IAEvB,OAAO,CACL,
|
|
1
|
+
{"version":3,"file":"HomePage.js","sourceRoot":"","sources":["../../../../shell/dev/devHome/HomePage.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,QAAQ,MAAM,YAAY,CAAC;AAElC,MAAM,CAAC,OAAO,UAAU,QAAQ;IAC9B,MAAM,aAAa,GAAG,iBAAiB,CAAC,sCAAsC,CAAC,CAAC;IAChF,MAAM,YAAY,GAAG,iBAAiB,CAAC,qCAAqC,CAAC,CAAC;IAC9E,MAAM,eAAe,GAAG,iBAAiB,CAAC,wCAAwC,CAAC,CAAC;IACpF,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IAEvB,OAAO,CACL,MAAC,SAAS,IAAC,KAAK,QAAC,IAAI,EAAC,IAAI,aACxB,sBAAI,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAK,EACjD,yBACG,aAAa,KAAK,IAAI,IAAI,CACzB,uBAAI,KAAC,IAAI,IAAC,EAAE,EAAE,aAAa,sCAA8B,GAAK,CAC/D,EACA,YAAY,KAAK,IAAI,IAAI,CACxB,uBAAI,KAAC,IAAI,IAAC,EAAE,EAAE,YAAY,qCAA6B,GAAK,CAC7D,EACA,eAAe,KAAK,IAAI,IAAI,CAC3B,uBAAI,KAAC,IAAI,IAAC,EAAE,EAAE,eAAe,yCAAiC,GAAK,CACpE,IACE,IACK,CACb,CAAC;AACJ,CAAC","sourcesContent":["import { Container } from '@openedx/paragon';\nimport { Link } from 'react-router-dom';\nimport { useIntl } from '../../../runtime';\nimport { getUrlByRouteRole } from '../../../runtime/routing';\nimport messages from './messages';\n\nexport default function HomePage() {\n const coursewareUrl = getUrlByRouteRole('org.openedx.frontend.role.courseware');\n const dashboardUrl = getUrlByRouteRole('org.openedx.frontend.role.dashboard');\n const slotShowcaseUrl = getUrlByRouteRole('org.openedx.frontend.role.slotShowcase');\n const intl = useIntl();\n\n return (\n <Container fluid size=\"xl\">\n <p>{intl.formatMessage(messages.homeContent)}</p>\n <ul>\n {coursewareUrl !== null && (\n <li><Link to={coursewareUrl}>Go to courseware page</Link></li>\n )}\n {dashboardUrl !== null && (\n <li><Link to={dashboardUrl}>Go to dashboard page</Link></li>\n )}\n {slotShowcaseUrl !== null && (\n <li><Link to={slotShowcaseUrl}>Go to slot showcase page</Link></li>\n )}\n </ul>\n </Container>\n );\n}\n"]}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
+
import { homeRole } from '../../constants';
|
|
1
2
|
import HomePage from './HomePage';
|
|
2
3
|
const app = {
|
|
3
4
|
appId: 'org.openedx.frontend.app.dev.home',
|
|
4
5
|
routes: [{
|
|
5
|
-
path: '/',
|
|
6
|
+
path: '/dev',
|
|
6
7
|
id: 'org.openedx.frontend.route.dev.home',
|
|
7
8
|
Component: HomePage,
|
|
8
9
|
handle: {
|
|
9
|
-
|
|
10
|
+
roles: [homeRole],
|
|
10
11
|
}
|
|
11
12
|
}],
|
|
12
13
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../../../shell/dev/devHome/app.ts"],"names":[],"mappings":"AACA,OAAO,QAAQ,MAAM,YAAY,CAAC;AAElC,MAAM,GAAG,GAAQ;IACf,KAAK,EAAE,mCAAmC;IAC1C,MAAM,EAAE,CAAC;YACP,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../../../shell/dev/devHome/app.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,QAAQ,MAAM,YAAY,CAAC;AAElC,MAAM,GAAG,GAAQ;IACf,KAAK,EAAE,mCAAmC;IAC1C,MAAM,EAAE,CAAC;YACP,IAAI,EAAE,MAAM;YACZ,EAAE,EAAE,qCAAqC;YACzC,SAAS,EAAE,QAAQ;YACnB,MAAM,EAAE;gBACN,KAAK,EAAE,CAAC,QAAQ,CAAC;aAClB;SACF,CAAC;CACH,CAAC;AAEF,eAAe,GAAG,CAAC","sourcesContent":["import { App } from '../../../types';\nimport { homeRole } from '../../constants';\nimport HomePage from './HomePage';\n\nconst app: App = {\n appId: 'org.openedx.frontend.app.dev.home',\n routes: [{\n path: '/dev',\n id: 'org.openedx.frontend.route.dev.home',\n Component: HomePage,\n handle: {\n roles: [homeRole],\n }\n }],\n};\n\nexport default app;\n"]}
|
|
@@ -12,6 +12,6 @@ function Section({ title, children }) {
|
|
|
12
12
|
return (_jsxs("div", { children: [_jsx("h3", { className: "text-primary-500", children: title }), children] }));
|
|
13
13
|
}
|
|
14
14
|
export default function SlotShowcasePage() {
|
|
15
|
-
return (_jsxs(Container, { size: "xl", className: "showcase-page py-4", children: [_jsxs("div", { className: "showcase-full-width", children: [_jsx("h1", { children: "Slot Showcase" }), _jsxs("p", { children: ["As a best practice, widgets should pass additional props (", _jsx("code", { children: "...props" }), ") to their rendered HTMLElement. This allows custom layouts to add ", _jsx("code", { children: "className" }), " and ", _jsx("code", { children: "style" }), " props as necessary for the layout."] })] }), _jsxs(Section, { title: "Simple slot with default layout", children: [_jsx("p", { children: "This slot has no opinionated layout, it just renders its children." }), _jsx(SlotContainer, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.dev.slotShowcaseSimple" }) })] }), _jsxs(Section, { title: "Simple slot with default content and props", children: [_jsx("p", { children: "This slot has default content, and it exposes a slot prop to widgets." }), _jsx(SlotContainer, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.dev.slotShowcaseSimpleWithDefaultContent", aSlotProp: "hello!", children: _jsx("div", { className: "showcase-widget", children: "Look, I'm default content!" }) }) })] }), _jsx("h2", { className: "showcase-divider", children: "UI Layout Operations" }), _jsxs(Section, { title: "Slot with custom layout (component)", children: [_jsx("p", { children: "This slot uses a horizontal flexbox layout from a component." }), _jsx(SlotContainer, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.dev.slotShowcaseCustom", layout: HorizontalSlotLayout }) })] }), _jsxs(Section, { title: "Slot with custom layout (element)", children: [_jsx("p", { children: "This slot uses a horizontal flexbox layout from a JSX element." }), _jsx(SlotContainer, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.dev.slotShowcaseCustom", layout: _jsx(HorizontalSlotLayout, {}) }) })] }), _jsxs(Section, { title: "Slot with override custom layout", children: [_jsx("p", { children: "This slot uses a horizontal flexbox layout, but it was added by a layout replace operation." }), _jsx(SlotContainer, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.dev.slotShowcaseCustomConfig" }) })] }), _jsxs(Section, { title: "Slot with layout options (default)", children: [_jsx("p", { children: "This slot uses a custom layout that takes options. It shows the default title." }), _jsx(SlotContainer, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.dev.slotShowcaseLayoutWithOptionsDefault", layout: LayoutWithOptions }) })] }), _jsxs(Section, { title: "Slot with layout options (configured)", children: [_jsx("p", { children: "Same layout, but the title option is set to \"Bar\"." }), _jsx(SlotContainer, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.dev.slotShowcaseLayoutWithOptions", layout: LayoutWithOptions }) })] }), _jsxs(Section, { title: "Slot with widget filtering by role", children: [_jsxs("p", { children: ["This slot has four widgets, two with a \"highlighted\" role. The layout uses ", _jsx("code", { children: "widgets.byRole()" }), " to toggle between all and highlighted."] }), _jsx(SlotContainer, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.dev.slotShowcaseFilterByRole", layout: ToggleByRoleLayout }) })] }), _jsx("h2", { className: "showcase-divider", children: "UI Widget Operations" }), _jsxs(Section, { title: "Slot with prepended element", children: [_jsx("p", { children: "This slot has a prepended element (and two appended elements)." }), _jsx(SlotContainer, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.dev.slotShowcasePrepending" }) })] }), _jsxs(Section, { title: "Slot with inserted elements", children: [_jsxs("p", { children: ["This slot has elements inserted before and after the second element. The insert operations are declared ", _jsx("em", { children: "before" }), " the related element, but can still insert themselves relative to it."] }), _jsx(SlotContainer, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.dev.slotShowcaseInserting" }) })] }), _jsxs(Section, { title: "Slot with replaced element", children: [_jsx("p", { children: "This slot has an element replacing element two." }), _jsx(SlotContainer, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.dev.slotShowcaseReplacing" }) })] }), _jsxs(Section, { title: "Slot with removed element", children: [_jsxs("p", { children: ["This slot has removed element two (", _jsx("code", { children: "WidgetOperationTypes.REMOVE" }), ")."] }), _jsx(SlotContainer, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.dev.slotShowcaseRemoving" }) })] }), _jsxs(Section, { title: "Slot with widget options (default)", children: [_jsx("p", { children: "This widget accepts options. It shows the default title." }), _jsx(SlotContainer, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.dev.slotShowcaseWidgetOptions" }) })] })] }));
|
|
15
|
+
return (_jsxs(Container, { fluid: true, size: "xl", className: "showcase-page py-4", children: [_jsxs("div", { className: "showcase-full-width", children: [_jsx("h1", { children: "Slot Showcase" }), _jsxs("p", { children: ["As a best practice, widgets should pass additional props (", _jsx("code", { children: "...props" }), ") to their rendered HTMLElement. This allows custom layouts to add ", _jsx("code", { children: "className" }), " and ", _jsx("code", { children: "style" }), " props as necessary for the layout."] })] }), _jsxs(Section, { title: "Simple slot with default layout", children: [_jsx("p", { children: "This slot has no opinionated layout, it just renders its children." }), _jsx(SlotContainer, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.dev.slotShowcaseSimple" }) })] }), _jsxs(Section, { title: "Simple slot with default content and props", children: [_jsx("p", { children: "This slot has default content, and it exposes a slot prop to widgets." }), _jsx(SlotContainer, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.dev.slotShowcaseSimpleWithDefaultContent", aSlotProp: "hello!", children: _jsx("div", { className: "showcase-widget", children: "Look, I'm default content!" }) }) })] }), _jsx("h2", { className: "showcase-divider", children: "UI Layout Operations" }), _jsxs(Section, { title: "Slot with custom layout (component)", children: [_jsx("p", { children: "This slot uses a horizontal flexbox layout from a component." }), _jsx(SlotContainer, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.dev.slotShowcaseCustom", layout: HorizontalSlotLayout }) })] }), _jsxs(Section, { title: "Slot with custom layout (element)", children: [_jsx("p", { children: "This slot uses a horizontal flexbox layout from a JSX element." }), _jsx(SlotContainer, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.dev.slotShowcaseCustom", layout: _jsx(HorizontalSlotLayout, {}) }) })] }), _jsxs(Section, { title: "Slot with override custom layout", children: [_jsx("p", { children: "This slot uses a horizontal flexbox layout, but it was added by a layout replace operation." }), _jsx(SlotContainer, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.dev.slotShowcaseCustomConfig" }) })] }), _jsxs(Section, { title: "Slot with layout options (default)", children: [_jsx("p", { children: "This slot uses a custom layout that takes options. It shows the default title." }), _jsx(SlotContainer, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.dev.slotShowcaseLayoutWithOptionsDefault", layout: LayoutWithOptions }) })] }), _jsxs(Section, { title: "Slot with layout options (configured)", children: [_jsx("p", { children: "Same layout, but the title option is set to \"Bar\"." }), _jsx(SlotContainer, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.dev.slotShowcaseLayoutWithOptions", layout: LayoutWithOptions }) })] }), _jsxs(Section, { title: "Slot with widget filtering by role", children: [_jsxs("p", { children: ["This slot has four widgets, two with a \"highlighted\" role. The layout uses ", _jsx("code", { children: "widgets.byRole()" }), " to toggle between all and highlighted."] }), _jsx(SlotContainer, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.dev.slotShowcaseFilterByRole", layout: ToggleByRoleLayout }) })] }), _jsx("h2", { className: "showcase-divider", children: "UI Widget Operations" }), _jsxs(Section, { title: "Slot with prepended element", children: [_jsx("p", { children: "This slot has a prepended element (and two appended elements)." }), _jsx(SlotContainer, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.dev.slotShowcasePrepending" }) })] }), _jsxs(Section, { title: "Slot with inserted elements", children: [_jsxs("p", { children: ["This slot has elements inserted before and after the second element. The insert operations are declared ", _jsx("em", { children: "before" }), " the related element, but can still insert themselves relative to it."] }), _jsx(SlotContainer, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.dev.slotShowcaseInserting" }) })] }), _jsxs(Section, { title: "Slot with replaced element", children: [_jsx("p", { children: "This slot has an element replacing element two." }), _jsx(SlotContainer, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.dev.slotShowcaseReplacing" }) })] }), _jsxs(Section, { title: "Slot with removed element", children: [_jsxs("p", { children: ["This slot has removed element two (", _jsx("code", { children: "WidgetOperationTypes.REMOVE" }), ")."] }), _jsx(SlotContainer, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.dev.slotShowcaseRemoving" }) })] }), _jsxs(Section, { title: "Slot with widget options (default)", children: [_jsx("p", { children: "This widget accepts options. It shows the default title." }), _jsx(SlotContainer, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.dev.slotShowcaseWidgetOptions" }) })] })] }));
|
|
16
16
|
}
|
|
17
17
|
//# sourceMappingURL=SlotShowcasePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SlotShowcasePage.js","sourceRoot":"","sources":["../../../../shell/dev/slotShowcase/SlotShowcasePage.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,oBAAoB,MAAM,wBAAwB,CAAC;AAC1D,OAAO,iBAAiB,MAAM,qBAAqB,CAAC;AACpD,OAAO,kBAAkB,MAAM,sBAAsB,CAAC;AACtD,OAAO,qBAAqB,CAAC;AAE7B,SAAS,aAAa,CAAC,EAAE,QAAQ,EAA2B;IAC1D,OAAO,CACL,KAAC,IAAI,IAAC,SAAS,EAAC,eAAe,YAC7B,KAAC,IAAI,CAAC,IAAI,cACP,QAAQ,GACC,GACP,CACR,CAAC;AACJ,CAAC;AAED,SAAS,OAAO,CAAC,EAAE,KAAK,EAAE,QAAQ,EAA0C;IAC1E,OAAO,CACL,0BACE,aAAI,SAAS,EAAC,kBAAkB,YAAE,KAAK,GAAM,EAC5C,QAAQ,IACL,CACP,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,gBAAgB;IACtC,OAAO,CACL,MAAC,SAAS,IAAC,IAAI,EAAC,IAAI,EAAC,SAAS,EAAC,oBAAoB,
|
|
1
|
+
{"version":3,"file":"SlotShowcasePage.js","sourceRoot":"","sources":["../../../../shell/dev/slotShowcase/SlotShowcasePage.tsx"],"names":[],"mappings":"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","sourcesContent":["import { ReactNode } from 'react';\nimport { Card, Container } from '@openedx/paragon';\nimport { Slot } from '../../../runtime';\nimport HorizontalSlotLayout from './HorizontalSlotLayout';\nimport LayoutWithOptions from './LayoutWithOptions';\nimport ToggleByRoleLayout from './ToggleByRoleLayout';\nimport './SlotShowcase.scss';\n\nfunction SlotContainer({ children }: { children: ReactNode }) {\n return (\n <Card className=\"showcase-slot\">\n <Card.Body>\n {children}\n </Card.Body>\n </Card>\n );\n}\n\nfunction Section({ title, children }: { title: string, children: ReactNode }) {\n return (\n <div>\n <h3 className=\"text-primary-500\">{title}</h3>\n {children}\n </div>\n );\n}\n\nexport default function SlotShowcasePage() {\n return (\n <Container fluid size=\"xl\" className=\"showcase-page py-4\">\n <div className=\"showcase-full-width\">\n <h1>Slot Showcase</h1>\n <p>As a best practice, widgets should pass additional props (<code>...props</code>) to their rendered HTMLElement. This allows custom layouts to add <code>className</code> and <code>style</code> props as necessary for the layout.</p>\n </div>\n\n <Section title=\"Simple slot with default layout\">\n <p>This slot has no opinionated layout, it just renders its children.</p>\n <SlotContainer>\n <Slot id=\"org.openedx.frontend.slot.dev.slotShowcaseSimple\" />\n </SlotContainer>\n </Section>\n\n <Section title=\"Simple slot with default content and props\">\n <p>This slot has default content, and it exposes a slot prop to widgets.</p>\n <SlotContainer>\n <Slot id=\"org.openedx.frontend.slot.dev.slotShowcaseSimpleWithDefaultContent\" aSlotProp=\"hello!\">\n <div className=\"showcase-widget\">Look, I'm default content!</div>\n </Slot>\n </SlotContainer>\n </Section>\n\n <h2 className=\"showcase-divider\">UI Layout Operations</h2>\n\n <Section title=\"Slot with custom layout (component)\">\n <p>This slot uses a horizontal flexbox layout from a component.</p>\n <SlotContainer>\n <Slot id=\"org.openedx.frontend.slot.dev.slotShowcaseCustom\" layout={HorizontalSlotLayout} />\n </SlotContainer>\n </Section>\n\n <Section title=\"Slot with custom layout (element)\">\n <p>This slot uses a horizontal flexbox layout from a JSX element.</p>\n <SlotContainer>\n <Slot id=\"org.openedx.frontend.slot.dev.slotShowcaseCustom\" layout={<HorizontalSlotLayout />} />\n </SlotContainer>\n </Section>\n\n <Section title=\"Slot with override custom layout\">\n <p>This slot uses a horizontal flexbox layout, but it was added by a layout replace operation.</p>\n <SlotContainer>\n <Slot id=\"org.openedx.frontend.slot.dev.slotShowcaseCustomConfig\" />\n </SlotContainer>\n </Section>\n\n <Section title=\"Slot with layout options (default)\">\n <p>This slot uses a custom layout that takes options. It shows the default title.</p>\n <SlotContainer>\n <Slot id=\"org.openedx.frontend.slot.dev.slotShowcaseLayoutWithOptionsDefault\" layout={LayoutWithOptions} />\n </SlotContainer>\n </Section>\n\n <Section title=\"Slot with layout options (configured)\">\n <p>Same layout, but the title option is set to "Bar".</p>\n <SlotContainer>\n <Slot id=\"org.openedx.frontend.slot.dev.slotShowcaseLayoutWithOptions\" layout={LayoutWithOptions} />\n </SlotContainer>\n </Section>\n\n <Section title=\"Slot with widget filtering by role\">\n <p>This slot has four widgets, two with a "highlighted" role. The layout uses <code>widgets.byRole()</code> to toggle between all and highlighted.</p>\n <SlotContainer>\n <Slot id=\"org.openedx.frontend.slot.dev.slotShowcaseFilterByRole\" layout={ToggleByRoleLayout} />\n </SlotContainer>\n </Section>\n\n <h2 className=\"showcase-divider\">UI Widget Operations</h2>\n\n <Section title=\"Slot with prepended element\">\n <p>This slot has a prepended element (and two appended elements).</p>\n <SlotContainer>\n <Slot id=\"org.openedx.frontend.slot.dev.slotShowcasePrepending\" />\n </SlotContainer>\n </Section>\n\n <Section title=\"Slot with inserted elements\">\n <p>This slot has elements inserted before and after the second element. The insert operations are declared <em>before</em> the related element, but can still insert themselves relative to it.</p>\n <SlotContainer>\n <Slot id=\"org.openedx.frontend.slot.dev.slotShowcaseInserting\" />\n </SlotContainer>\n </Section>\n\n <Section title=\"Slot with replaced element\">\n <p>This slot has an element replacing element two.</p>\n <SlotContainer>\n <Slot id=\"org.openedx.frontend.slot.dev.slotShowcaseReplacing\" />\n </SlotContainer>\n </Section>\n\n <Section title=\"Slot with removed element\">\n <p>This slot has removed element two (<code>WidgetOperationTypes.REMOVE</code>).</p>\n <SlotContainer>\n <Slot id=\"org.openedx.frontend.slot.dev.slotShowcaseRemoving\" />\n </SlotContainer>\n </Section>\n\n <Section title=\"Slot with widget options (default)\">\n <p>This widget accepts options. It shows the default title.</p>\n <SlotContainer>\n <Slot id=\"org.openedx.frontend.slot.dev.slotShowcaseWidgetOptions\" />\n </SlotContainer>\n </Section>\n\n </Container>\n );\n}\n"]}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import { Person } from '@openedx/paragon/icons';
|
|
2
|
+
import { AvatarButton, Dropdown } from '@openedx/paragon';
|
|
4
3
|
import { Slot, useAuthenticatedUser } from '../../runtime';
|
|
5
4
|
export default function AuthenticatedMenu({ className }) {
|
|
6
5
|
const authenticatedUser = useAuthenticatedUser();
|
|
7
6
|
const displayUserName = (authenticatedUser === null || authenticatedUser === void 0 ? void 0 : authenticatedUser.name) || (authenticatedUser === null || authenticatedUser === void 0 ? void 0 : authenticatedUser.username);
|
|
8
|
-
|
|
9
|
-
return (_jsx(DropdownButton, { size: "sm", id: "user-nav-dropdown", title: title, variant: "outline-primary", className: className, children: _jsx(Slot, { id: "org.openedx.frontend.slot.header.authenticatedMenu.v1" }) }));
|
|
7
|
+
return (_jsxs(Dropdown, { className: className, children: [_jsx(Dropdown.Toggle, { as: AvatarButton, id: "user-nav-dropdown", variant: "outline-primary", src: authenticatedUser === null || authenticatedUser === void 0 ? void 0 : authenticatedUser.avatar, children: displayUserName }), _jsx(Dropdown.Menu, { children: _jsx(Slot, { id: "org.openedx.frontend.slot.header.authenticatedMenu.v1" }) })] }));
|
|
10
8
|
}
|
|
11
9
|
//# sourceMappingURL=AuthenticatedMenu.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthenticatedMenu.js","sourceRoot":"","sources":["../../../shell/header/AuthenticatedMenu.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"AuthenticatedMenu.js","sourceRoot":"","sources":["../../../shell/header/AuthenticatedMenu.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE1D,OAAO,EACL,IAAI,EACJ,oBAAoB,EACrB,MAAM,eAAe,CAAC;AAMvB,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,EAAE,SAAS,EAA0B;IAC7E,MAAM,iBAAiB,GAAG,oBAAoB,EAAE,CAAC;IAEjD,MAAM,eAAe,GAAG,CAAA,iBAAiB,aAAjB,iBAAiB,uBAAjB,iBAAiB,CAAE,IAAI,MAAI,iBAAiB,aAAjB,iBAAiB,uBAAjB,iBAAiB,CAAE,QAAQ,CAAA,CAAC;IAE/E,OAAO,CACL,MAAC,QAAQ,IAAC,SAAS,EAAE,SAAS,aAC5B,KAAC,QAAQ,CAAC,MAAM,IACd,EAAE,EAAE,YAAY,EAChB,EAAE,EAAC,mBAAmB,EACtB,OAAO,EAAC,iBAAiB,EACzB,GAAG,EAAE,iBAAiB,aAAjB,iBAAiB,uBAAjB,iBAAiB,CAAE,MAAM,YAE7B,eAAe,GACA,EAClB,KAAC,QAAQ,CAAC,IAAI,cACZ,KAAC,IAAI,IAAC,EAAE,EAAC,uDAAuD,GAAG,GACrD,IACP,CACZ,CAAC;AACJ,CAAC","sourcesContent":["import { AvatarButton, Dropdown } from '@openedx/paragon';\n\nimport {\n Slot,\n useAuthenticatedUser\n} from '../../runtime';\n\ninterface AuthenticatedMenuProps {\n className?: string,\n}\n\nexport default function AuthenticatedMenu({ className }: AuthenticatedMenuProps) {\n const authenticatedUser = useAuthenticatedUser();\n\n const displayUserName = authenticatedUser?.name || authenticatedUser?.username;\n\n return (\n <Dropdown className={className}>\n <Dropdown.Toggle\n as={AvatarButton}\n id=\"user-nav-dropdown\"\n variant=\"outline-primary\"\n src={authenticatedUser?.avatar}\n >\n {displayUserName}\n </Dropdown.Toggle>\n <Dropdown.Menu>\n <Slot id=\"org.openedx.frontend.slot.header.authenticatedMenu.v1\" />\n </Dropdown.Menu>\n </Dropdown>\n );\n}\n"]}
|
|
@@ -3,6 +3,6 @@ import { Slot, useIntl } from '../../runtime';
|
|
|
3
3
|
import messages from '../Shell.messages';
|
|
4
4
|
export default function Header() {
|
|
5
5
|
const intl = useIntl();
|
|
6
|
-
return (_jsxs(_Fragment, { children: [_jsx("header", { className: "border-bottom
|
|
6
|
+
return (_jsxs(_Fragment, { children: [_jsx("header", { className: "border-bottom", children: _jsxs("nav", { children: [_jsx("a", { className: "sr-only sr-only-focusable", href: "#main-content", children: intl.formatMessage(messages.skipNavLink) }), _jsx(Slot, { id: "org.openedx.frontend.slot.header.desktop.v1" }), _jsx(Slot, { id: "org.openedx.frontend.slot.header.mobile.v1" })] }) }), _jsx(Slot, { id: "org.openedx.frontend.slot.header.courseNavigationBar.v1" })] }));
|
|
7
7
|
}
|
|
8
8
|
//# sourceMappingURL=Header.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Header.js","sourceRoot":"","sources":["../../../shell/header/Header.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE9C,OAAO,QAAQ,MAAM,mBAAmB,CAAC;AAEzC,MAAM,CAAC,OAAO,UAAU,MAAM;IAC5B,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IAEvB,OAAO,CACL,8BACE,iBAAQ,SAAS,EAAC,
|
|
1
|
+
{"version":3,"file":"Header.js","sourceRoot":"","sources":["../../../shell/header/Header.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE9C,OAAO,QAAQ,MAAM,mBAAmB,CAAC;AAEzC,MAAM,CAAC,OAAO,UAAU,MAAM;IAC5B,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IAEvB,OAAO,CACL,8BACE,iBAAQ,SAAS,EAAC,eAAe,YAC/B,0BACE,YAAG,SAAS,EAAC,2BAA2B,EAAC,IAAI,EAAC,eAAe,YAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAK,EAC5G,KAAC,IAAI,IAAC,EAAE,EAAC,6CAA6C,GAAG,EACzD,KAAC,IAAI,IAAC,EAAE,EAAC,4CAA4C,GAAG,IACpD,GACC,EACT,KAAC,IAAI,IAAC,EAAE,EAAC,yDAAyD,GAAG,IACpE,CACJ,CAAC;AACJ,CAAC","sourcesContent":["import { Slot, useIntl } from '../../runtime';\n\nimport messages from '../Shell.messages';\n\nexport default function Header() {\n const intl = useIntl();\n\n return (\n <>\n <header className=\"border-bottom\">\n <nav>\n <a className=\"sr-only sr-only-focusable\" href=\"#main-content\">{intl.formatMessage(messages.skipNavLink)}</a>\n <Slot id=\"org.openedx.frontend.slot.header.desktop.v1\" />\n <Slot id=\"org.openedx.frontend.slot.header.mobile.v1\" />\n </nav>\n </header>\n <Slot id=\"org.openedx.frontend.slot.header.courseNavigationBar.v1\" />\n </>\n );\n}\n"]}
|
package/dist/shell/header/app.js
CHANGED
|
@@ -14,6 +14,7 @@ import messages from '../Shell.messages';
|
|
|
14
14
|
import CourseTabsNavigation from './course-navigation-bar/CourseTabsNavigation';
|
|
15
15
|
import { isCourseNavigationRoute } from './course-navigation-bar/utils';
|
|
16
16
|
import { appId } from './constants';
|
|
17
|
+
import './app.scss';
|
|
17
18
|
const config = {
|
|
18
19
|
appId,
|
|
19
20
|
slots: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../../shell/header/app.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAErD,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,YAAY,MAAM,uBAAuB,CAAC;AACjD,OAAO,mBAAmB,MAAM,8BAA8B,CAAC;AAC/D,OAAO,aAAa,MAAM,gCAAgC,CAAC;AAC3D,OAAO,iBAAiB,MAAM,qBAAqB,CAAC;AACpD,OAAO,aAAa,MAAM,yBAAyB,CAAC;AACpD,OAAO,eAAe,MAAM,2BAA2B,CAAC;AACxD,OAAO,iBAAiB,MAAM,6BAA6B,CAAC;AAC5D,OAAO,YAAY,MAAM,uBAAuB,CAAC;AACjD,OAAO,cAAc,MAAM,yBAAyB,CAAC;AAErD,OAAO,QAAQ,MAAM,mBAAmB,CAAC;AACzC,OAAO,oBAAoB,MAAM,8CAA8C,CAAC;AAChF,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../../shell/header/app.tsx"],"names":[],"mappings":"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","sourcesContent":["import { WidgetOperationTypes } from '../../runtime';\nimport { App } from '../../types';\nimport Logo from '../Logo';\nimport LinkMenuItem from '../menus/LinkMenuItem';\nimport ProfileLinkMenuItem from '../menus/ProfileLinkMenuItem';\nimport AnonymousMenu from './anonymous-menu/AnonymousMenu';\nimport AuthenticatedMenu from './AuthenticatedMenu';\nimport DesktopLayout from './desktop/DesktopLayout';\nimport PrimaryNavLinks from './desktop/PrimaryNavLinks';\nimport SecondaryNavLinks from './desktop/SecondaryNavLinks';\nimport MobileLayout from './mobile/MobileLayout';\nimport MobileNavLinks from './mobile/MobileNavLinks';\n\nimport messages from '../Shell.messages';\nimport CourseTabsNavigation from './course-navigation-bar/CourseTabsNavigation';\nimport { isCourseNavigationRoute } from './course-navigation-bar/utils';\nimport { appId } from './constants';\nimport './app.scss';\n\nconst config: App = {\n appId,\n slots: [\n // Layouts\n {\n slotId: 'org.openedx.frontend.slot.header.desktop.v1',\n id: 'org.openedx.frontend.widget.header.desktopLayout.v1',\n op: WidgetOperationTypes.APPEND,\n component: DesktopLayout\n },\n {\n slotId: 'org.openedx.frontend.slot.header.mobile.v1',\n id: 'org.openedx.frontend.widget.header.mobileLayout.v1',\n op: WidgetOperationTypes.APPEND,\n component: MobileLayout\n },\n\n // Desktop\n {\n slotId: 'org.openedx.frontend.slot.header.desktopLeft.v1',\n id: 'org.openedx.frontend.widget.header.desktopLogo.v1',\n op: WidgetOperationTypes.APPEND,\n element: <Logo />,\n },\n {\n slotId: 'org.openedx.frontend.slot.header.desktopLeft.v1',\n id: 'org.openedx.frontend.widget.header.desktopPrimaryLinks.v1',\n op: WidgetOperationTypes.APPEND,\n component: PrimaryNavLinks\n },\n {\n slotId: 'org.openedx.frontend.slot.header.desktopRight.v1',\n id: 'org.openedx.frontend.widget.header.desktopSecondaryLinks.v1',\n op: WidgetOperationTypes.APPEND,\n component: SecondaryNavLinks\n },\n {\n slotId: 'org.openedx.frontend.slot.header.desktopRight.v1',\n id: 'org.openedx.frontend.widget.header.desktopAuthenticatedMenu.v1',\n op: WidgetOperationTypes.APPEND,\n element: <AuthenticatedMenu />,\n condition: {\n authenticated: true,\n }\n },\n {\n slotId: 'org.openedx.frontend.slot.header.authenticatedMenu.v1',\n id: 'org.openedx.frontend.widget.header.desktopAuthenticatedMenuProfile.v1',\n op: WidgetOperationTypes.APPEND,\n element: (\n <ProfileLinkMenuItem\n label={messages['header.user.menu.profile']}\n role=\"org.openedx.frontend.role.profile\"\n variant=\"dropdownItem\"\n />\n )\n },\n {\n slotId: 'org.openedx.frontend.slot.header.authenticatedMenu.v1',\n id: 'org.openedx.frontend.widget.header.desktopAuthenticatedMenuAccount.v1',\n op: WidgetOperationTypes.APPEND,\n element: (\n <LinkMenuItem\n label={messages['header.user.menu.account']}\n role=\"org.openedx.frontend.role.account\"\n variant=\"dropdownItem\"\n />\n )\n },\n {\n slotId: 'org.openedx.frontend.slot.header.authenticatedMenu.v1',\n id: 'org.openedx.frontend.widget.header.desktopAuthenticatedMenuLogout.v1',\n op: WidgetOperationTypes.APPEND,\n element: (\n <LinkMenuItem\n label={messages['header.user.menu.logout']}\n role=\"org.openedx.frontend.role.logout\"\n variant=\"dropdownItem\"\n />\n )\n },\n {\n slotId: 'org.openedx.frontend.slot.header.desktopRight.v1',\n id: 'org.openedx.frontend.widget.header.desktopAnonymousMenu.v1',\n op: WidgetOperationTypes.APPEND,\n element: <AnonymousMenu />,\n condition: {\n authenticated: false,\n }\n },\n\n // Mobile\n {\n slotId: 'org.openedx.frontend.slot.header.mobileCenter.v1',\n id: 'org.openedx.frontend.widget.header.mobileLogo.v1',\n op: WidgetOperationTypes.APPEND,\n element: <Logo />,\n },\n {\n slotId: 'org.openedx.frontend.slot.header.mobileMenu.v1',\n id: 'org.openedx.frontend.widget.header.mobileMenuLinks.v1',\n op: WidgetOperationTypes.APPEND,\n component: MobileNavLinks\n },\n {\n slotId: 'org.openedx.frontend.slot.header.mobileRight.v1',\n id: 'org.openedx.frontend.widget.header.mobileAuthenticatedMenu.v1',\n op: WidgetOperationTypes.APPEND,\n element: <AuthenticatedMenu />,\n condition: {\n authenticated: true,\n }\n },\n {\n slotId: 'org.openedx.frontend.slot.header.mobileRight.v1',\n id: 'org.openedx.frontend.widget.header.mobileAnonymousMenu.v1',\n op: WidgetOperationTypes.APPEND,\n element: <AnonymousMenu />,\n condition: {\n authenticated: false,\n }\n },\n {\n slotId: 'org.openedx.frontend.slot.header.courseNavigationBar.v1',\n id: 'org.openedx.frontend.widget.header.courseNavigationBar.v1',\n op: WidgetOperationTypes.APPEND,\n component: CourseTabsNavigation,\n condition: {\n callback: () => isCourseNavigationRoute(),\n }\n }\n ]\n};\n\nexport default config;\n"]}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Container } from '@openedx/paragon';
|
|
2
3
|
import classNames from 'classnames';
|
|
3
4
|
import { useMediaQuery } from 'react-responsive';
|
|
4
5
|
import { Slot } from '../../../runtime';
|
|
5
6
|
export default function DesktopLayout() {
|
|
6
7
|
const isMobile = useMediaQuery({ maxWidth: 768 });
|
|
7
|
-
return (_jsxs("
|
|
8
|
+
return (_jsxs(Container, { fluid: true, size: "xl", className: classNames('align-items-center justify-content-between', isMobile ? 'd-none' : 'd-flex'), children: [_jsx("div", { className: "d-flex flex-grow-1 align-items-center", children: _jsx(Slot, { id: "org.openedx.frontend.slot.header.desktopLeft.v1" }) }), _jsx("div", { className: "d-flex align-items-center", children: _jsx(Slot, { id: "org.openedx.frontend.slot.header.desktopRight.v1" }) })] }));
|
|
8
9
|
}
|
|
9
10
|
//# sourceMappingURL=DesktopLayout.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DesktopLayout.js","sourceRoot":"","sources":["../../../../shell/header/desktop/DesktopLayout.tsx"],"names":[],"mappings":";AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,MAAM,CAAC,OAAO,UAAU,aAAa;IACnC,MAAM,QAAQ,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;IAElD,OAAO,CACL,
|
|
1
|
+
{"version":3,"file":"DesktopLayout.js","sourceRoot":"","sources":["../../../../shell/header/desktop/DesktopLayout.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,MAAM,CAAC,OAAO,UAAU,aAAa;IACnC,MAAM,QAAQ,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;IAElD,OAAO,CACL,MAAC,SAAS,IACR,KAAK,QACL,IAAI,EAAC,IAAI,EACT,SAAS,EAAE,UAAU,CACnB,4CAA4C,EAC5C,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAC/B,aAED,cAAK,SAAS,EAAC,uCAAuC,YACpD,KAAC,IAAI,IAAC,EAAE,EAAC,iDAAiD,GAAG,GACzD,EACN,cAAK,SAAS,EAAC,2BAA2B,YACxC,KAAC,IAAI,IAAC,EAAE,EAAC,kDAAkD,GAAG,GAC1D,IACI,CACb,CAAC;AACJ,CAAC","sourcesContent":["import { Container } from '@openedx/paragon';\nimport classNames from 'classnames';\nimport { useMediaQuery } from 'react-responsive';\nimport { Slot } from '../../../runtime';\n\nexport default function DesktopLayout() {\n const isMobile = useMediaQuery({ maxWidth: 768 });\n\n return (\n <Container\n fluid\n size=\"xl\"\n className={classNames(\n 'align-items-center justify-content-between',\n isMobile ? 'd-none' : 'd-flex'\n )}\n >\n <div className=\"d-flex flex-grow-1 align-items-center\">\n <Slot id=\"org.openedx.frontend.slot.header.desktopLeft.v1\" />\n </div>\n <div className=\"d-flex align-items-center\">\n <Slot id=\"org.openedx.frontend.slot.header.desktopRight.v1\" />\n </div>\n </Container>\n );\n}\n"]}
|
|
@@ -2,6 +2,6 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { Nav } from '@openedx/paragon';
|
|
3
3
|
import { Slot } from '../../../runtime';
|
|
4
4
|
export default function PrimaryNavLinks() {
|
|
5
|
-
return (_jsx(Nav, { className: "flex-nowrap align-items-center", children: _jsx(Slot, { id: "org.openedx.frontend.slot.header.primaryLinks.v1" }) }));
|
|
5
|
+
return (_jsx(Nav, { className: "flex-nowrap align-items-center ml-3", children: _jsx(Slot, { id: "org.openedx.frontend.slot.header.primaryLinks.v1" }) }));
|
|
6
6
|
}
|
|
7
7
|
//# sourceMappingURL=PrimaryNavLinks.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PrimaryNavLinks.js","sourceRoot":"","sources":["../../../../shell/header/desktop/PrimaryNavLinks.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,MAAM,CAAC,OAAO,UAAU,eAAe;IACrC,OAAO,CACL,KAAC,GAAG,IAAC,SAAS,EAAC,
|
|
1
|
+
{"version":3,"file":"PrimaryNavLinks.js","sourceRoot":"","sources":["../../../../shell/header/desktop/PrimaryNavLinks.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,MAAM,CAAC,OAAO,UAAU,eAAe;IACrC,OAAO,CACL,KAAC,GAAG,IAAC,SAAS,EAAC,qCAAqC,YAClD,KAAC,IAAI,IAAC,EAAE,EAAC,kDAAkD,GAAG,GAC1D,CACP,CAAC;AACJ,CAAC","sourcesContent":["import { Nav } from '@openedx/paragon';\nimport { Slot } from '../../../runtime';\n\nexport default function PrimaryNavLinks() {\n return (\n <Nav className=\"flex-nowrap align-items-center ml-3\">\n <Slot id=\"org.openedx.frontend.slot.header.primaryLinks.v1\" />\n </Nav>\n );\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { Button, Nav } from '@openedx/paragon';
|
|
2
|
+
import { Button, Container, Nav } from '@openedx/paragon';
|
|
3
3
|
import { MenuIcon } from '@openedx/paragon/icons';
|
|
4
4
|
import classNames from 'classnames';
|
|
5
5
|
import { useCallback, useState } from 'react';
|
|
@@ -12,6 +12,6 @@ export default function MobileLayout() {
|
|
|
12
12
|
const handleMobileButtonClick = useCallback(() => {
|
|
13
13
|
setMobileOpen((value) => !value);
|
|
14
14
|
}, []);
|
|
15
|
-
return (_jsxs(_Fragment, { children: [_jsxs("
|
|
15
|
+
return (_jsxs(_Fragment, { children: [_jsxs(Container, { fluid: true, size: "xl", className: classNames('align-items-center justify-content-between', isMobile ? 'd-flex' : 'd-none'), children: [_jsxs("div", { className: "d-flex flex-grow-1 flex-basis-0 justify-content-start align-items-center", children: [_jsx(Button, { onClick: handleMobileButtonClick, variant: "outline", children: _jsx(MenuIcon, {}) }), _jsx(Slot, { id: "org.openedx.frontend.slot.header.mobileLeft.v1" })] }), _jsx("div", { className: "d-flex flex-grow-1 flex-basis-0 justify-content-center align-items-center", children: _jsx(Slot, { id: "org.openedx.frontend.slot.header.mobileCenter.v1" }) }), _jsx("div", { className: "d-flex flex-grow-1 flex-basis-0 justify-content-end align-items-center", children: _jsx(Slot, { id: "org.openedx.frontend.slot.header.mobileRight.v1" }) })] }), mobileOpen && (_jsx(FocusOn, { onClickOutside: () => setMobileOpen(false), onEscapeKey: () => setMobileOpen(false), children: _jsx(Nav, { className: "flex-column", children: _jsx(Slot, { id: "org.openedx.frontend.slot.header.mobileMenuLinks.v1" }) }) }))] }));
|
|
16
16
|
}
|
|
17
17
|
//# sourceMappingURL=MobileLayout.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MobileLayout.js","sourceRoot":"","sources":["../../../../shell/header/mobile/MobileLayout.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"MobileLayout.js","sourceRoot":"","sources":["../../../../shell/header/mobile/MobileLayout.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,MAAM,CAAC,OAAO,UAAU,YAAY;IAClC,MAAM,QAAQ,GAAG,aAAa,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;IAClD,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAC;IAE7D,MAAM,uBAAuB,GAAG,WAAW,CAAC,GAAG,EAAE;QAC/C,aAAa,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CACL,8BACE,MAAC,SAAS,IACR,KAAK,QACL,IAAI,EAAC,IAAI,EACT,SAAS,EAAE,UAAU,CACnB,4CAA4C,EAC5C,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAC/B,aAED,eAAK,SAAS,EAAC,0EAA0E,aACvF,KAAC,MAAM,IAAC,OAAO,EAAE,uBAAuB,EAAE,OAAO,EAAC,SAAS,YACzD,KAAC,QAAQ,KAAG,GACL,EACT,KAAC,IAAI,IAAC,EAAE,EAAC,gDAAgD,GAAG,IACxD,EACN,cAAK,SAAS,EAAC,2EAA2E,YACxF,KAAC,IAAI,IAAC,EAAE,EAAC,kDAAkD,GAAG,GAC1D,EACN,cAAK,SAAS,EAAC,wEAAwE,YACrF,KAAC,IAAI,IAAC,EAAE,EAAC,iDAAiD,GAAG,GACzD,IACI,EACX,UAAU,IAAI,CACb,KAAC,OAAO,IAAC,cAAc,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,YAC1F,KAAC,GAAG,IAAC,SAAS,EAAC,aAAa,YAC1B,KAAC,IAAI,IAAC,EAAE,EAAC,qDAAqD,GAAG,GAC7D,GACE,CACX,IACA,CACJ,CAAC;AACJ,CAAC","sourcesContent":["import { Button, Container, Nav } from '@openedx/paragon';\nimport { MenuIcon } from '@openedx/paragon/icons';\nimport classNames from 'classnames';\nimport { useCallback, useState } from 'react';\nimport { FocusOn } from 'react-focus-on';\nimport { useMediaQuery } from 'react-responsive';\nimport { Slot } from '../../../runtime';\n\nexport default function MobileLayout() {\n const isMobile = useMediaQuery({ maxWidth: 768 });\n const [mobileOpen, setMobileOpen] = useState<boolean>(false);\n\n const handleMobileButtonClick = useCallback(() => {\n setMobileOpen((value) => !value);\n }, []);\n\n return (\n <>\n <Container\n fluid\n size=\"xl\"\n className={classNames(\n 'align-items-center justify-content-between',\n isMobile ? 'd-flex' : 'd-none',\n )}\n >\n <div className=\"d-flex flex-grow-1 flex-basis-0 justify-content-start align-items-center\">\n <Button onClick={handleMobileButtonClick} variant=\"outline\">\n <MenuIcon />\n </Button>\n <Slot id=\"org.openedx.frontend.slot.header.mobileLeft.v1\" />\n </div>\n <div className=\"d-flex flex-grow-1 flex-basis-0 justify-content-center align-items-center\">\n <Slot id=\"org.openedx.frontend.slot.header.mobileCenter.v1\" />\n </div>\n <div className=\"d-flex flex-grow-1 flex-basis-0 justify-content-end align-items-center\">\n <Slot id=\"org.openedx.frontend.slot.header.mobileRight.v1\" />\n </div>\n </Container>\n {mobileOpen && (\n <FocusOn onClickOutside={() => setMobileOpen(false)} onEscapeKey={() => setMobileOpen(false)}>\n <Nav className=\"flex-column\">\n <Slot id=\"org.openedx.frontend.slot.header.mobileMenuLinks.v1\" />\n </Nav>\n </FocusOn>\n )}\n </>\n );\n}\n"]}
|
package/dist/shell/index.d.ts
CHANGED
|
@@ -3,6 +3,6 @@ export { default as DefaultMain } from './DefaultMain';
|
|
|
3
3
|
export { default as shellApp } from './app';
|
|
4
4
|
export { Footer, footerApp } from './footer';
|
|
5
5
|
export { providesCourseNavigationRolesId, Header, headerApp } from './header';
|
|
6
|
-
export { providesChromelessRolesId } from './constants';
|
|
6
|
+
export { homeRole, providesChromelessRolesId } from './constants';
|
|
7
7
|
export { default as LinkMenuItem } from './menus/LinkMenuItem';
|
|
8
8
|
export { default as NavDropdownMenuSlot } from './menus/NavDropdownMenuSlot';
|
package/dist/shell/index.js
CHANGED
|
@@ -3,7 +3,7 @@ export { default as DefaultMain } from './DefaultMain';
|
|
|
3
3
|
export { default as shellApp } from './app';
|
|
4
4
|
export { Footer, footerApp } from './footer';
|
|
5
5
|
export { providesCourseNavigationRolesId, Header, headerApp } from './header';
|
|
6
|
-
export { providesChromelessRolesId } from './constants';
|
|
6
|
+
export { homeRole, providesChromelessRolesId } from './constants';
|
|
7
7
|
export { default as LinkMenuItem } from './menus/LinkMenuItem';
|
|
8
8
|
export { default as NavDropdownMenuSlot } from './menus/NavDropdownMenuSlot';
|
|
9
9
|
//# sourceMappingURL=index.js.map
|
package/dist/shell/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../shell/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,+BAA+B,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC9E,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../shell/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,+BAA+B,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC9E,OAAO,EAAE,QAAQ,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,6BAA6B,CAAC","sourcesContent":["export { default as DefaultLayout } from './DefaultLayout';\nexport { default as DefaultMain } from './DefaultMain';\nexport { default as shellApp } from './app';\nexport { Footer, footerApp } from './footer';\nexport { providesCourseNavigationRolesId, Header, headerApp } from './header';\nexport { homeRole, providesChromelessRolesId } from './constants';\nexport { default as LinkMenuItem } from './menus/LinkMenuItem';\nexport { default as NavDropdownMenuSlot } from './menus/NavDropdownMenuSlot';\n"]}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Dropdown, Hyperlink, NavDropdown, NavLink } from '@openedx/paragon';
|
|
3
3
|
import { useIntl } from 'react-intl';
|
|
4
|
+
import { useLocation } from 'react-router-dom';
|
|
4
5
|
import { getUrlByRouteRole } from '../../runtime/routing';
|
|
5
6
|
import { getItemLabel } from './data/utils';
|
|
6
7
|
export default function LinkMenuItem({ label, role, url, variant = 'hyperlink' }) {
|
|
7
8
|
const intl = useIntl();
|
|
9
|
+
const location = useLocation();
|
|
8
10
|
const finalLabel = getItemLabel(label, intl);
|
|
9
11
|
let finalUrl;
|
|
10
12
|
if (role !== undefined) {
|
|
@@ -22,7 +24,7 @@ export default function LinkMenuItem({ label, role, url, variant = 'hyperlink' }
|
|
|
22
24
|
return (_jsx(Hyperlink, { destination: finalUrl, children: finalLabel }));
|
|
23
25
|
}
|
|
24
26
|
else if (variant === 'navLink') {
|
|
25
|
-
return (_jsx(NavLink, { href: finalUrl, children: finalLabel }));
|
|
27
|
+
return (_jsx(NavLink, { href: finalUrl, active: location.pathname.replace(/\/$/, '') === finalUrl.replace(/\/$/, ''), children: finalLabel }));
|
|
26
28
|
}
|
|
27
29
|
else if (variant === 'navDropdownItem') {
|
|
28
30
|
return (_jsx(NavDropdown.Item, { href: finalUrl, children: finalLabel }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LinkMenuItem.js","sourceRoot":"","sources":["../../../shell/menus/LinkMenuItem.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"LinkMenuItem.js","sourceRoot":"","sources":["../../../shell/menus/LinkMenuItem.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAI1D,OAAO,EACL,YAAY,EACb,MAAM,cAAc,CAAC;AAStB,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,GAAG,WAAW,EAAqB;IACjG,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAE7C,IAAI,QAAmC,CAAC;IACxC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,QAAQ,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;SAAM,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QAC7B,QAAQ,GAAG,GAAG,CAAC;IACjB,CAAC;IAED,6FAA6F;IAC7F,sDAAsD;IACtD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;QAC5B,OAAO,CACL,KAAC,SAAS,IAAC,WAAW,EAAE,QAAQ,YAC7B,UAAU,GACD,CACb,CAAC;IACJ,CAAC;SAAM,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QACjC,OAAO,CACL,KAAC,OAAO,IAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,YAClG,UAAU,GACH,CACX,CAAC;IACJ,CAAC;SAAM,IAAI,OAAO,KAAK,iBAAiB,EAAE,CAAC;QACzC,OAAO,CACL,KAAC,WAAW,CAAC,IAAI,IAAC,IAAI,EAAE,QAAQ,YAC7B,UAAU,GACM,CACpB,CAAC;IACJ,CAAC;SAAM,IAAI,OAAO,KAAK,cAAc,EAAE,CAAC;QACtC,OAAO,CACL,KAAC,QAAQ,CAAC,IAAI,IAAC,IAAI,EAAE,QAAQ,YAC1B,UAAU,GACG,CACjB,CAAC;IACJ,CAAC;IAED,4EAA4E;IAC5E,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import { Dropdown, Hyperlink, NavDropdown, NavLink } from '@openedx/paragon';\nimport { useIntl } from 'react-intl';\nimport { useLocation } from 'react-router-dom';\n\nimport { getUrlByRouteRole } from '../../runtime/routing';\nimport {\n MenuItemName\n} from '../../types';\nimport {\n getItemLabel\n} from './data/utils';\n\ninterface LinkMenuItemProps {\n label: MenuItemName,\n role?: string,\n url?: string,\n variant?: 'hyperlink' | 'navLink' | 'navDropdownItem' | 'dropdownItem',\n}\n\nexport default function LinkMenuItem({ label, role, url, variant = 'hyperlink' }: LinkMenuItemProps) {\n const intl = useIntl();\n const location = useLocation();\n const finalLabel = getItemLabel(label, intl);\n\n let finalUrl: string | null | undefined;\n if (role !== undefined) {\n finalUrl = getUrlByRouteRole(role);\n } else if (url !== undefined) {\n finalUrl = url;\n }\n\n // The URL will only be null if the item is an \"app\" menu item, and if the app is not loaded.\n // We automatically hide the link if this is the case.\n if (!finalUrl) {\n return null;\n }\n\n if (variant === 'hyperlink') {\n return (\n <Hyperlink destination={finalUrl}>\n {finalLabel}\n </Hyperlink>\n );\n } else if (variant === 'navLink') {\n return (\n <NavLink href={finalUrl} active={location.pathname.replace(/\\/$/, '') === finalUrl.replace(/\\/$/, '')}>\n {finalLabel}\n </NavLink>\n );\n } else if (variant === 'navDropdownItem') {\n return (\n <NavDropdown.Item href={finalUrl}>\n {finalLabel}\n </NavDropdown.Item>\n );\n } else if (variant === 'dropdownItem') {\n return (\n <Dropdown.Item href={finalUrl}>\n {finalLabel}\n </Dropdown.Item>\n );\n }\n\n // Just return null if the item is something we haven't accounted for above.\n return null;\n}\n"]}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { redirect } from 'react-router';
|
|
2
|
+
import { getSiteConfig, getUrlByRouteRole } from '../../runtime';
|
|
3
|
+
import { homeRole } from '../constants';
|
|
2
4
|
export default function getAppRoutes() {
|
|
3
5
|
const { apps } = getSiteConfig();
|
|
4
6
|
let routes = [];
|
|
@@ -9,6 +11,17 @@ export default function getAppRoutes() {
|
|
|
9
11
|
}
|
|
10
12
|
});
|
|
11
13
|
}
|
|
14
|
+
/*
|
|
15
|
+
* If any app claims the home role, append a redirect from / to that URL.
|
|
16
|
+
* Appended last so that an app with its own / route takes priority.
|
|
17
|
+
*/
|
|
18
|
+
const homeUrl = getUrlByRouteRole(homeRole);
|
|
19
|
+
if (homeUrl) {
|
|
20
|
+
routes.push({
|
|
21
|
+
path: '/',
|
|
22
|
+
loader: () => redirect(homeUrl),
|
|
23
|
+
});
|
|
24
|
+
}
|
|
12
25
|
return routes;
|
|
13
26
|
}
|
|
14
27
|
//# sourceMappingURL=getAppRoutes.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getAppRoutes.js","sourceRoot":"","sources":["../../../shell/router/getAppRoutes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"getAppRoutes.js","sourceRoot":"","sources":["../../../shell/router/getAppRoutes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAe,MAAM,cAAc,CAAC;AAErD,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEjE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,MAAM,CAAC,OAAO,UAAU,YAAY;IAClC,MAAM,EAAE,IAAI,EAAE,GAAG,aAAa,EAAE,CAAC;IAEjC,IAAI,MAAM,GAAkB,EAAE,CAAC;IAE/B,IAAI,IAAI,EAAE,CAAC;QACT,IAAI,CAAC,OAAO,CACV,CAAC,GAAQ,EAAE,EAAE;YACX,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC9B,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACrC,CAAC;QACH,CAAC,CACF,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,MAAM,OAAO,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAC5C,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,GAAG;YACT,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC;SAChC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import { redirect, RouteObject } from 'react-router';\n\nimport { getSiteConfig, getUrlByRouteRole } from '../../runtime';\nimport { App } from '../../types';\nimport { homeRole } from '../constants';\n\nexport default function getAppRoutes() {\n const { apps } = getSiteConfig();\n\n let routes: RouteObject[] = [];\n\n if (apps) {\n apps.forEach(\n (app: App) => {\n if (Array.isArray(app.routes)) {\n routes = routes.concat(app.routes);\n }\n }\n );\n }\n\n /*\n * If any app claims the home role, append a redirect from / to that URL.\n * Appended last so that an app with its own / route takes priority.\n */\n const homeUrl = getUrlByRouteRole(homeRole);\n if (homeUrl) {\n routes.push({\n path: '/',\n loader: () => redirect(homeUrl),\n });\n }\n\n return routes;\n}\n"]}
|
package/dist/shell/site.js
CHANGED
|
@@ -7,8 +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 { jsx as _jsx } from "react/jsx-runtime";
|
|
11
|
-
import { StrictMode } from 'react';
|
|
10
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
|
+
import { lazy, StrictMode, Suspense } from 'react';
|
|
12
12
|
import { createRoot } from 'react-dom/client';
|
|
13
13
|
import { RouterProvider } from 'react-router-dom';
|
|
14
14
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
@@ -16,12 +16,23 @@ import { SITE_INIT_ERROR, SITE_READY, initialize, subscribe } from '../runtime';
|
|
|
16
16
|
import { addAppConfigs } from '../runtime/config';
|
|
17
17
|
import messages from 'site.i18n';
|
|
18
18
|
import createRouter from './router/createRouter';
|
|
19
|
+
/*
|
|
20
|
+
* Use a dynamic import guarded by process.env.NODE_ENV so that webpack
|
|
21
|
+
* places the devtools in a separate async chunk that is only requested
|
|
22
|
+
* in development. In production the ternary resolves to null and the
|
|
23
|
+
* chunk is never loaded.
|
|
24
|
+
*/
|
|
25
|
+
const ReactQueryDevtools = process.env.NODE_ENV === 'development'
|
|
26
|
+
? lazy(() => import('@tanstack/react-query-devtools')
|
|
27
|
+
.then((m) => ({ default: m.ReactQueryDevtools }))
|
|
28
|
+
.catch(() => ({ default: () => null })))
|
|
29
|
+
: null;
|
|
19
30
|
subscribe(SITE_READY, () => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
31
|
const queryClient = new QueryClient();
|
|
21
32
|
const router = createRouter();
|
|
22
33
|
addAppConfigs();
|
|
23
34
|
const root = createRoot(document.getElementById('root'));
|
|
24
|
-
root.render(_jsx(StrictMode, { children:
|
|
35
|
+
root.render(_jsx(StrictMode, { children: _jsxs(QueryClientProvider, { client: queryClient, children: [_jsx(RouterProvider, { router: router }), ReactQueryDevtools && (_jsx(Suspense, { fallback: null, children: _jsx(ReactQueryDevtools, { initialIsOpen: false }) }))] }) }));
|
|
25
36
|
}));
|
|
26
37
|
subscribe(SITE_INIT_ERROR, (error) => {
|
|
27
38
|
const root = createRoot(document.getElementById('root'));
|
package/dist/shell/site.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"site.js","sourceRoot":"","sources":["../../shell/site.tsx"],"names":[],"mappings":";;;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"site.js","sourceRoot":"","sources":["../../shell/site.tsx"],"names":[],"mappings":";;;;;;;;;;AAAA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAEzE,OAAO,EACL,eAAe,EACf,UAAU,EACV,UAAU,EACV,SAAS,EACV,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,QAAQ,MAAM,WAAW,CAAC;AACjC,OAAO,YAAY,MAAM,uBAAuB,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa;IAC/D,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,gCAAgC,CAAC;SAChD,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAC;SAChD,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC5C,CAAC,CAAC,IAAI,CAAC;AAET,SAAS,CAAC,UAAU,EAAE,GAAS,EAAE;IAC/B,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;IACtC,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAE9B,aAAa,EAAE,CAAC;IAEhB,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAgB,CAAC,CAAC;IACxE,IAAI,CAAC,MAAM,CACT,KAAC,UAAU,cACT,MAAC,mBAAmB,IAAC,MAAM,EAAE,WAAW,aACtC,KAAC,cAAc,IAAC,MAAM,EAAE,MAAM,GAAI,EACjC,kBAAkB,IAAI,CACrB,KAAC,QAAQ,IAAC,QAAQ,EAAE,IAAI,YACtB,KAAC,kBAAkB,IAAC,aAAa,EAAE,KAAK,GAAI,GACnC,CACZ,IACmB,GACX,CACd,CAAC;AACJ,CAAC,CAAA,CAAC,CAAC;AAEH,SAAS,CAAC,eAAe,EAAE,CAAC,KAAK,EAAE,EAAE;IACnC,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAgB,CAAC,CAAC;IACxE,IAAI,CAAC,MAAM,CAAC,wBAAM,KAAK,CAAC,OAAO,GAAO,CAAC,CAAC;AAC1C,CAAC,CAAC,CAAC;AAEH,UAAU,CAAC;IACT,QAAQ;CACT,CAAC,CAAC","sourcesContent":["import { lazy, StrictMode, Suspense } from 'react';\nimport { createRoot } from 'react-dom/client';\nimport { RouterProvider } from 'react-router-dom';\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\n\nimport {\n SITE_INIT_ERROR,\n SITE_READY,\n initialize,\n subscribe\n} from '../runtime';\nimport { addAppConfigs } from '../runtime/config';\nimport messages from 'site.i18n';\nimport createRouter from './router/createRouter';\n\n/*\n * Use a dynamic import guarded by process.env.NODE_ENV so that webpack\n * places the devtools in a separate async chunk that is only requested\n * in development. In production the ternary resolves to null and the\n * chunk is never loaded.\n */\nconst ReactQueryDevtools = process.env.NODE_ENV === 'development'\n ? lazy(() => import('@tanstack/react-query-devtools')\n .then((m) => ({ default: m.ReactQueryDevtools }))\n .catch(() => ({ default: () => null })))\n : null;\n\nsubscribe(SITE_READY, async () => {\n const queryClient = new QueryClient();\n const router = createRouter();\n\n addAppConfigs();\n\n const root = createRoot(document.getElementById('root') as HTMLElement);\n root.render(\n <StrictMode>\n <QueryClientProvider client={queryClient}>\n <RouterProvider router={router} />\n {ReactQueryDevtools && (\n <Suspense fallback={null}>\n <ReactQueryDevtools initialIsOpen={false} />\n </Suspense>\n )}\n </QueryClientProvider>\n </StrictMode>\n );\n});\n\nsubscribe(SITE_INIT_ERROR, (error) => {\n const root = createRoot(document.getElementById('root') as HTMLElement);\n root.render(<div>{error.message}</div>);\n});\n\ninitialize({\n messages,\n});\n"]}
|
package/dist/types.d.ts
CHANGED
|
@@ -9,9 +9,9 @@ export interface ExternalRoute {
|
|
|
9
9
|
export type RoleRouteObject = RouteObject & {
|
|
10
10
|
handle?: {
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* Route roles identify the purpose(s) a route fulfills in the site.
|
|
13
13
|
*/
|
|
14
|
-
|
|
14
|
+
roles?: string[];
|
|
15
15
|
};
|
|
16
16
|
};
|
|
17
17
|
export type AppConfig = Record<string, unknown>;
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../types.ts"],"names":[],"mappings":"AAiHA,MAAM,CAAN,IAAY,gBAIX;AAJD,WAAY,gBAAgB;IAC1B,6CAAyB,CAAA;IACzB,+CAA2B,CAAA;IAC3B,iCAAa,CAAA;AACf,CAAC,EAJW,gBAAgB,KAAhB,gBAAgB,QAI3B","sourcesContent":["import { FC, ReactElement, ReactNode } from 'react';\nimport { MessageDescriptor } from 'react-intl';\nimport { RouteObject } from 'react-router';\nimport { SlotOperation } from './runtime/slots/types';\n\n// Apps\n\nexport interface ExternalRoute {\n role: string,\n url: string,\n}\n\nexport type RoleRouteObject = RouteObject & {\n handle?: {\n /**\n *
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../types.ts"],"names":[],"mappings":"AAiHA,MAAM,CAAN,IAAY,gBAIX;AAJD,WAAY,gBAAgB;IAC1B,6CAAyB,CAAA;IACzB,+CAA2B,CAAA;IAC3B,iCAAa,CAAA;AACf,CAAC,EAJW,gBAAgB,KAAhB,gBAAgB,QAI3B","sourcesContent":["import { FC, ReactElement, ReactNode } from 'react';\nimport { MessageDescriptor } from 'react-intl';\nimport { RouteObject } from 'react-router';\nimport { SlotOperation } from './runtime/slots/types';\n\n// Apps\n\nexport interface ExternalRoute {\n role: string,\n url: string,\n}\n\nexport type RoleRouteObject = RouteObject & {\n handle?: {\n /**\n * Route roles identify the purpose(s) a route fulfills in the site.\n */\n roles?: string[],\n },\n};\n\nexport type AppConfig = Record<string, unknown>;\n\nexport type AppProvider = FC<{ children?: ReactNode }>;\n\nexport interface App {\n appId: string,\n routes?: RoleRouteObject[],\n providers?: AppProvider[],\n slots?: SlotOperation[],\n config?: AppConfig,\n provides?: Record<string, unknown>,\n}\n\n// Site Config\n\nexport interface RequiredSiteConfig {\n siteId: string,\n siteName: string,\n baseUrl: string,\n\n // Backends\n lmsBaseUrl: string,\n\n // Frontends\n loginUrl: string,\n logoutUrl: string,\n}\n\nexport type LocalizedMessages = Record<string, Record<string, string>>;\nexport type SiteMessages = LocalizedMessages[];\n\nexport interface OptionalSiteConfig {\n // Site environment\n environment: EnvironmentTypes,\n\n // Apps, routes, and URLs\n apps: App[],\n basename: string,\n externalRoutes: ExternalRoute[],\n externalLinkUrlOverrides: string[],\n runtimeConfigJsonUrl: string | null,\n commonAppConfig: AppConfig,\n headerLogoImageUrl: string,\n\n // Theme\n theme: Theme,\n\n // Cookies\n accessTokenCookieName: string,\n languagePreferenceCookieName: string,\n userInfoCookieName: string,\n\n // Paths\n csrfTokenApiPath: string,\n refreshAccessTokenApiPath: string,\n\n // Logging\n ignoredErrorRegex: RegExp | null,\n\n // Analytics\n segmentKey: string | null,\n}\n\nexport type SiteConfig = RequiredSiteConfig & Partial<OptionalSiteConfig>;\n\nexport interface ThemeVariant {\n url: string,\n}\n\nexport interface ThemeDefaults {\n light?: string,\n dark?: string,\n}\n\nexport type ThemeVariants = Record<string, ThemeVariant>;\n\nexport interface Theme {\n core?: ThemeVariant,\n defaults?: ThemeDefaults,\n variants?: ThemeVariants,\n}\n\nexport interface User {\n administrator: boolean,\n email: string,\n name: string,\n roles: string[],\n userId: number,\n username: string,\n avatar: string,\n}\n\nexport enum EnvironmentTypes {\n PRODUCTION = 'production',\n DEVELOPMENT = 'development',\n TEST = 'test',\n}\n\n// Menu Items\n\nexport type MenuItemName = string | MessageDescriptor | ReactElement;\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openedx/frontend-base",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.26",
|
|
4
4
|
"description": "Build tools, setup and config for frontend apps",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -68,6 +68,7 @@
|
|
|
68
68
|
"@formatjs/ts-transformer": "^3.13.14",
|
|
69
69
|
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.15",
|
|
70
70
|
"@stylistic/eslint-plugin": "^2.9.0",
|
|
71
|
+
"@tanstack/react-query-devtools": "^5.99.0",
|
|
71
72
|
"@types/eslint__js": "^8.42.3",
|
|
72
73
|
"@types/gradient-string": "^1.1.6",
|
|
73
74
|
"@types/lodash.keyby": "^4.6.9",
|