@openedx/frontend-base 1.0.1 → 2.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/README.md +1 -1
  2. package/dist/runtime/config/index.js.map +1 -1
  3. package/dist/runtime/i18n/index.d.ts +26 -3
  4. package/dist/runtime/i18n/index.js +2 -53
  5. package/dist/runtime/i18n/index.js.map +1 -1
  6. package/dist/runtime/i18n/lib.d.ts +0 -12
  7. package/dist/runtime/i18n/lib.js +0 -12
  8. package/dist/runtime/i18n/lib.js.map +1 -1
  9. package/dist/runtime/index.d.ts +1 -1
  10. package/dist/runtime/index.js +1 -1
  11. package/dist/runtime/index.js.map +1 -1
  12. package/dist/runtime/jest.config.js +1 -1
  13. package/dist/runtime/jest.config.js.map +1 -1
  14. package/dist/runtime/logging/types.js.map +1 -1
  15. package/dist/runtime/react/CombinedAppProvider.js.map +1 -1
  16. package/dist/runtime/react/CurrentAppContext.js.map +1 -1
  17. package/dist/runtime/react/CurrentAppProvider.js.map +1 -1
  18. package/dist/runtime/react/SiteContext.js.map +1 -1
  19. package/dist/runtime/react/SiteProvider.js.map +1 -1
  20. package/dist/runtime/react/hooks/theme/useThemeVariants.js.map +1 -1
  21. package/dist/runtime/slots/Slot.js.map +1 -1
  22. package/dist/runtime/slots/SlotContext.js.map +1 -1
  23. package/dist/runtime/slots/layout/types.js.map +1 -1
  24. package/dist/runtime/slots/types.js.map +1 -1
  25. package/dist/runtime/slots/widget/WidgetContext.js.map +1 -1
  26. package/dist/runtime/slots/widget/WidgetProvider.js.map +1 -1
  27. package/dist/runtime/slots/widget/iframe/IFrameContentWrapper.js.map +1 -1
  28. package/dist/runtime/slots/widget/iframe/IFrameWidget.js.map +1 -1
  29. package/dist/runtime/slots/widget/iframe/hooks.js.map +1 -1
  30. package/dist/runtime/slots/widget/iframe/types.js.map +1 -1
  31. package/dist/runtime/slots/widget/types.js.map +1 -1
  32. package/dist/runtime/testing/initializeMockApp.js.map +1 -1
  33. package/dist/shell/Logo.js.map +1 -1
  34. package/dist/shell/dev/devHeader/BarContext.js.map +1 -1
  35. package/dist/shell/dev/devHeader/BarProvider.js.map +1 -1
  36. package/dist/shell/dev/devHeader/FooContext.js.map +1 -1
  37. package/dist/shell/dev/devHeader/FooProvider.js.map +1 -1
  38. package/dist/shell/dev/slotShowcase/SlotShowcasePage.js.map +1 -1
  39. package/dist/shell/dev/slotShowcase/app.js.map +1 -1
  40. package/dist/shell/footer/CopyrightNotice.js.map +1 -1
  41. package/dist/shell/footer/LanguageMenuItem.js.map +1 -1
  42. package/dist/shell/header/AuthenticatedMenu.js.map +1 -1
  43. package/dist/shell/header/HelpButton.js.map +1 -1
  44. package/dist/shell/header/anonymous-menu/AnonymousMenu.js.map +1 -1
  45. package/dist/shell/header/course-bar/data/service.js.map +1 -1
  46. package/dist/shell/header/course-bar/masquerade/StudioLink.js.map +1 -1
  47. package/dist/shell/header/course-bar/masquerade/data/api.js.map +1 -1
  48. package/dist/shell/header/course-bar/masquerade/hooks.js.map +1 -1
  49. package/dist/shell/header/course-bar/masquerade/masquerade-widget/MasqueradeUserNameInput.js.map +1 -1
  50. package/dist/shell/header/course-bar/masquerade/masquerade-widget/MasqueradeWidgetOption.js.map +1 -1
  51. package/dist/shell/header/course-bar/navigation/CourseTabsNavigation.js.map +1 -1
  52. package/dist/shell/header/helpButtonSlotOperation.js.map +1 -1
  53. package/dist/shell/jest.config.js +1 -1
  54. package/dist/shell/jest.config.js.map +1 -1
  55. package/dist/shell/menus/LinkMenuItem.js.map +1 -1
  56. package/dist/shell/menus/NavDropdownMenuSlot.js.map +1 -1
  57. package/dist/shell/menus/ProfileLinkMenuItem.js.map +1 -1
  58. package/dist/tools/eslint/base.eslint.config.js +2 -2
  59. package/dist/tools/jest/jest.config.js +1 -1
  60. package/dist/tools/jest.config.js +1 -1
  61. package/dist/types.js.map +1 -1
  62. package/package.json +3 -3
  63. package/dist/runtime/i18n/injectIntlWithShim.d.ts +0 -11
  64. package/dist/runtime/i18n/injectIntlWithShim.js +0 -45
  65. package/dist/runtime/i18n/injectIntlWithShim.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"WidgetProvider.js","sourceRoot":"","sources":["../../../../runtime/slots/widget/WidgetProvider.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAa,SAAS,EAAE,MAAM,OAAO,CAAC;AAE7C,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAS5C,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAuB;IAC9F,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QACD,OAAO,GAAG,EAAE;YACV,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,sBAAsB,CAAC,IAAI,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,OAAO,CACL,KAAC,aAAa,CAAC,QAAQ,IAAC,KAAK,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,YACtD,QAAQ,GACc,CAC1B,CAAC;AACJ,CAAC","sourcesContent":["import { ReactNode, useEffect } from 'react';\n\nimport { addActiveWidgetRole, removeActiveWidgetRole } from '../../config';\nimport WidgetContext from './WidgetContext';\n\ninterface WidgetProviderProps {\n children: ReactNode,\n slotId: string,\n widgetId: string,\n role?: string,\n}\n\nexport default function WidgetProvider({ children, slotId, widgetId, role }: WidgetProviderProps) {\n useEffect(() => {\n if (role !== undefined) {\n addActiveWidgetRole(role);\n }\n return () => {\n if (role !== undefined) {\n removeActiveWidgetRole(role);\n }\n };\n }, [role]);\n\n return (\n <WidgetContext.Provider value={{ slotId, widgetId, role }}>\n {children}\n </WidgetContext.Provider>\n );\n}\n"]}
1
+ {"version":3,"file":"WidgetProvider.js","sourceRoot":"","sources":["../../../../runtime/slots/widget/WidgetProvider.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAa,SAAS,EAAE,MAAM,OAAO,CAAC;AAE7C,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAS5C,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAuB;IAC9F,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QACD,OAAO,GAAG,EAAE;YACV,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,sBAAsB,CAAC,IAAI,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,OAAO,CACL,KAAC,aAAa,CAAC,QAAQ,IAAC,KAAK,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,YACtD,QAAQ,GACc,CAC1B,CAAC;AACJ,CAAC","sourcesContent":["import { ReactNode, useEffect } from 'react';\n\nimport { addActiveWidgetRole, removeActiveWidgetRole } from '../../config';\nimport WidgetContext from './WidgetContext';\n\ninterface WidgetProviderProps {\n children: ReactNode;\n slotId: string;\n widgetId: string;\n role?: string;\n}\n\nexport default function WidgetProvider({ children, slotId, widgetId, role }: WidgetProviderProps) {\n useEffect(() => {\n if (role !== undefined) {\n addActiveWidgetRole(role);\n }\n return () => {\n if (role !== undefined) {\n removeActiveWidgetRole(role);\n }\n };\n }, [role]);\n\n return (\n <WidgetContext.Provider value={{ slotId, widgetId, role }}>\n {children}\n </WidgetContext.Provider>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"IFrameContentWrapper.js","sourceRoot":"","sources":["../../../../../runtime/slots/widget/iframe/IFrameContentWrapper.tsx"],"names":[],"mappings":";AAAA,OAAO,EAGL,SAAS,EAAE,OAAO,EAAE,QAAQ,GAC7B,MAAM,OAAO,CAAC;AAEf,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACtB,YAAY,EACb,MAAM,SAAS,CAAC;AACjB,OAAO,QAAQ,MAAM,iCAAiC,CAAC;AAEvD,MAAM,oBAAoB,GAAG,GAAG,EAAE;IAChC,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,OAAO,CACL,wBACE,uBACG,aAAa,CAAC,QAAQ,CAAC,eAAe,CAAC,GACrC,GACD,CACP,CAAC;AACJ,CAAC,CAAC;AAUF,MAAM,CAAC,OAAO,UAAU,oBAAoB,CAAC,EAC3C,QAAQ,EAAE,SAAS,EAAE,KAAK,GAAG,EAAE,EAAE,KAAK,GAAG,IAAI,EAAE,sBAAsB,GAC3C;IAC1B,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC;QAC3C,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,CAAC;KACV,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,iCAC5B,UAAU,GACV,KAAK,EACR,EAAE,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;IAEzB,6GAA6G;IAE7G,MAAM,aAAa,GAAG,sBAAsB,aAAtB,sBAAsB,cAAtB,sBAAsB,GAAI,oBAAoB,CAAC;IAErE,YAAY,CAAC,aAAa,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;QAC1C,aAAa,CAAC;YACZ,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,oBAAoB,EAAE,CAAC;QAEvB,OAAO,GAAG,EAAE;YACV,sBAAsB,EAAE,CAAC;QAC3B,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,SAAS,CAAC,GAAG,EAAE;QACb,gGAAgG;QAChG,4CAA4C;QAC5C,IAAI,KAAK,EAAE,CAAC;YACV,kBAAkB,EAAE,CAAC;QACvB,CAAC;IACH,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,OAAO,CACL,cAAK,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,YAC1C,KAAC,aAAa,IAAC,iBAAiB,EAAE,KAAC,aAAa,KAAG,YAChD,QAAQ,GACK,GACZ,CACP,CAAC;AACJ,CAAC;AAAA,CAAC","sourcesContent":["import {\n FunctionComponent,\n ReactNode,\n useEffect, useMemo, useState,\n} from 'react';\n\nimport { useIntl } from '../../../i18n';\nimport { ErrorBoundary } from '../../../react';\nimport { IFRAME_RESIZE } from './constants';\nimport {\n dispatchMountedEvent,\n dispatchReadyEvent,\n dispatchUnmountedEvent,\n useHostEvent\n} from './hooks';\nimport messages from './IFrameContentWrapper.messages';\n\nconst ErrorFallbackDefault = () => {\n const { formatMessage } = useIntl();\n return (\n <div>\n <h2>\n {formatMessage(messages.unexpectedError)}\n </h2>\n </div>\n );\n};\n\ninterface IFrameContentWrapperProps {\n children: ReactNode,\n className?: string,\n style?: Record<string, string>,\n ready?: boolean,\n errorFallbackComponent?: FunctionComponent,\n}\n\nexport default function IFrameContentWrapper({\n children, className, style = {}, ready = true, errorFallbackComponent,\n}: IFrameContentWrapperProps) {\n const [dimensions, setDimensions] = useState({\n width: 0,\n height: 0,\n });\n\n const finalStyle = useMemo(() => ({\n ...dimensions,\n ...style,\n }), [dimensions, style]);\n\n // Need to confirm: When an error is caught here, the logging will be sent to the child MFE's logging service\n\n const ErrorFallback = errorFallbackComponent ?? ErrorFallbackDefault;\n\n useHostEvent(IFRAME_RESIZE, ({ payload }) => {\n setDimensions({\n width: payload.width,\n height: payload.height,\n });\n });\n\n useEffect(() => {\n dispatchMountedEvent();\n\n return () => {\n dispatchUnmountedEvent();\n };\n }, []);\n\n useEffect(() => {\n // Ready defaults to true, but can be used to defer rendering the Plugin until certain processes\n // have occurred or conditions have been met\n if (ready) {\n dispatchReadyEvent();\n }\n }, [ready]);\n\n return (\n <div className={className} style={finalStyle}>\n <ErrorBoundary fallbackComponent={<ErrorFallback />}>\n {children}\n </ErrorBoundary>\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"IFrameContentWrapper.js","sourceRoot":"","sources":["../../../../../runtime/slots/widget/iframe/IFrameContentWrapper.tsx"],"names":[],"mappings":";AAAA,OAAO,EAGL,SAAS,EAAE,OAAO,EAAE,QAAQ,GAC7B,MAAM,OAAO,CAAC;AAEf,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACtB,YAAY,EACb,MAAM,SAAS,CAAC;AACjB,OAAO,QAAQ,MAAM,iCAAiC,CAAC;AAEvD,MAAM,oBAAoB,GAAG,GAAG,EAAE;IAChC,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,OAAO,CACL,wBACE,uBACG,aAAa,CAAC,QAAQ,CAAC,eAAe,CAAC,GACrC,GACD,CACP,CAAC;AACJ,CAAC,CAAC;AAUF,MAAM,CAAC,OAAO,UAAU,oBAAoB,CAAC,EAC3C,QAAQ,EAAE,SAAS,EAAE,KAAK,GAAG,EAAE,EAAE,KAAK,GAAG,IAAI,EAAE,sBAAsB,GAC3C;IAC1B,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC;QAC3C,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,CAAC;KACV,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,iCAC5B,UAAU,GACV,KAAK,EACR,EAAE,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;IAEzB,6GAA6G;IAE7G,MAAM,aAAa,GAAG,sBAAsB,aAAtB,sBAAsB,cAAtB,sBAAsB,GAAI,oBAAoB,CAAC;IAErE,YAAY,CAAC,aAAa,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;QAC1C,aAAa,CAAC;YACZ,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,oBAAoB,EAAE,CAAC;QAEvB,OAAO,GAAG,EAAE;YACV,sBAAsB,EAAE,CAAC;QAC3B,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,SAAS,CAAC,GAAG,EAAE;QACb,gGAAgG;QAChG,4CAA4C;QAC5C,IAAI,KAAK,EAAE,CAAC;YACV,kBAAkB,EAAE,CAAC;QACvB,CAAC;IACH,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,OAAO,CACL,cAAK,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,YAC1C,KAAC,aAAa,IAAC,iBAAiB,EAAE,KAAC,aAAa,KAAG,YAChD,QAAQ,GACK,GACZ,CACP,CAAC;AACJ,CAAC;AAAA,CAAC","sourcesContent":["import {\n FunctionComponent,\n ReactNode,\n useEffect, useMemo, useState,\n} from 'react';\n\nimport { useIntl } from '../../../i18n';\nimport { ErrorBoundary } from '../../../react';\nimport { IFRAME_RESIZE } from './constants';\nimport {\n dispatchMountedEvent,\n dispatchReadyEvent,\n dispatchUnmountedEvent,\n useHostEvent\n} from './hooks';\nimport messages from './IFrameContentWrapper.messages';\n\nconst ErrorFallbackDefault = () => {\n const { formatMessage } = useIntl();\n return (\n <div>\n <h2>\n {formatMessage(messages.unexpectedError)}\n </h2>\n </div>\n );\n};\n\ninterface IFrameContentWrapperProps {\n children: ReactNode;\n className?: string;\n style?: Record<string, string>;\n ready?: boolean;\n errorFallbackComponent?: FunctionComponent;\n}\n\nexport default function IFrameContentWrapper({\n children, className, style = {}, ready = true, errorFallbackComponent,\n}: IFrameContentWrapperProps) {\n const [dimensions, setDimensions] = useState({\n width: 0,\n height: 0,\n });\n\n const finalStyle = useMemo(() => ({\n ...dimensions,\n ...style,\n }), [dimensions, style]);\n\n // Need to confirm: When an error is caught here, the logging will be sent to the child MFE's logging service\n\n const ErrorFallback = errorFallbackComponent ?? ErrorFallbackDefault;\n\n useHostEvent(IFRAME_RESIZE, ({ payload }) => {\n setDimensions({\n width: payload.width,\n height: payload.height,\n });\n });\n\n useEffect(() => {\n dispatchMountedEvent();\n\n return () => {\n dispatchUnmountedEvent();\n };\n }, []);\n\n useEffect(() => {\n // Ready defaults to true, but can be used to defer rendering the Plugin until certain processes\n // have occurred or conditions have been met\n if (ready) {\n dispatchReadyEvent();\n }\n }, [ready]);\n\n return (\n <div className={className} style={finalStyle}>\n <ErrorBoundary fallbackComponent={<ErrorFallback />}>\n {children}\n </ErrorBoundary>\n </div>\n );\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"IFrameWidget.js","sourceRoot":"","sources":["../../../../../runtime/slots/widget/iframe/IFrameWidget.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC9E,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAOjG,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EAAE,GAAG,EAAE,KAAK,EAAqB;IACpE,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE1C,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,CAAC;IAEnF,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,EAAE,CAAC;YACZ,mBAAmB,CAAC,aAAkC,EAAE;gBACtD,IAAI,EAAE,aAAa;gBACnB,OAAO,EAAE;oBACP,KAAK;oBACL,MAAM;iBACP;aACF,EAAE,GAAG,CAAC,CAAC;QACV,CAAC;IACH,CAAC,EAAE,CAAC,aAAa,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;IAEjD,cAAc,CAAC,aAAa,EAAE,cAAc,EAAE,GAAG,EAAE;QACjD,UAAU,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,cAAc,CAAC,aAAa,EAAE,YAAY,EAAE,GAAG,EAAE;QAC/C,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,CACf,KAAC,OAAO,IAAC,SAAS,EAAC,QAAQ,EAAC,OAAO,EAAC,OAAO,EAAC,gBAAgB,EAAC,SAAS,GAAG,CAC1E,CAAC;IAEF,OAAO,CACL,8BACE,iBACE,GAAG,EAAE,SAAS,EACd,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,qBAAqB,EAC5B,cAAc,EAAC,QAAQ,CAAC,qGAAqG;kBAC7H,SAAS,EAAE,UAAU,CACnB,uBAAuB,EACvB,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,CACrB,GACD,EACD,CAAC,KAAK,IAAI,QAAQ,IAClB,CACJ,CAAC;AACJ,CAAC","sourcesContent":["import { Spinner } from '@openedx/paragon';\nimport { useEffect, useState } from 'react';\n\nimport classNames from 'classnames';\nimport { dispatchPluginEvent, useElementSize, usePluginEvent } from './hooks';\nimport { IFRAME_FEATURE_POLICY, IFRAME_MOUNTED, IFRAME_READY, IFRAME_RESIZE } from './constants';\n\ninterface IFrameWidgetProps {\n url: string,\n title: string,\n}\n\nexport default function IFrameWidget({ url, title }: IFrameWidgetProps) {\n const [mounted, setMounted] = useState(false);\n const [ready, setReady] = useState(false);\n\n const { ref: iframeRef, element: iframeElement, width, height } = useElementSize();\n\n useEffect(() => {\n if (mounted) {\n dispatchPluginEvent(iframeElement as HTMLIFrameElement, {\n type: IFRAME_RESIZE,\n payload: {\n width,\n height,\n },\n }, url);\n }\n }, [iframeElement, mounted, width, height, url]);\n\n usePluginEvent(iframeElement, IFRAME_MOUNTED, () => {\n setMounted(true);\n });\n\n usePluginEvent(iframeElement, IFRAME_READY, () => {\n setReady(true);\n });\n\n const fallback = (\n <Spinner animation=\"border\" variant=\"light\" screenReaderText=\"Loading\" />\n );\n\n return (\n <>\n <iframe\n ref={iframeRef}\n title={title}\n src={url}\n allow={IFRAME_FEATURE_POLICY}\n referrerPolicy=\"origin\" // The sent referrer will be limited to the origin of the referring page: its scheme, host, and port.\n className={classNames(\n 'border border-0 w-100',\n { 'd-none': !ready },\n )}\n />\n {!ready && fallback}\n </>\n );\n}\n"]}
1
+ {"version":3,"file":"IFrameWidget.js","sourceRoot":"","sources":["../../../../../runtime/slots/widget/iframe/IFrameWidget.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC9E,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAOjG,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EAAE,GAAG,EAAE,KAAK,EAAqB;IACpE,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE1C,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,CAAC;IAEnF,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,EAAE,CAAC;YACZ,mBAAmB,CAAC,aAAkC,EAAE;gBACtD,IAAI,EAAE,aAAa;gBACnB,OAAO,EAAE;oBACP,KAAK;oBACL,MAAM;iBACP;aACF,EAAE,GAAG,CAAC,CAAC;QACV,CAAC;IACH,CAAC,EAAE,CAAC,aAAa,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;IAEjD,cAAc,CAAC,aAAa,EAAE,cAAc,EAAE,GAAG,EAAE;QACjD,UAAU,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,cAAc,CAAC,aAAa,EAAE,YAAY,EAAE,GAAG,EAAE;QAC/C,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,CACf,KAAC,OAAO,IAAC,SAAS,EAAC,QAAQ,EAAC,OAAO,EAAC,OAAO,EAAC,gBAAgB,EAAC,SAAS,GAAG,CAC1E,CAAC;IAEF,OAAO,CACL,8BACE,iBACE,GAAG,EAAE,SAAS,EACd,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,qBAAqB,EAC5B,cAAc,EAAC,QAAQ,CAAC,qGAAqG;kBAC7H,SAAS,EAAE,UAAU,CACnB,uBAAuB,EACvB,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,CACrB,GACD,EACD,CAAC,KAAK,IAAI,QAAQ,IAClB,CACJ,CAAC;AACJ,CAAC","sourcesContent":["import { Spinner } from '@openedx/paragon';\nimport { useEffect, useState } from 'react';\n\nimport classNames from 'classnames';\nimport { dispatchPluginEvent, useElementSize, usePluginEvent } from './hooks';\nimport { IFRAME_FEATURE_POLICY, IFRAME_MOUNTED, IFRAME_READY, IFRAME_RESIZE } from './constants';\n\ninterface IFrameWidgetProps {\n url: string;\n title: string;\n}\n\nexport default function IFrameWidget({ url, title }: IFrameWidgetProps) {\n const [mounted, setMounted] = useState(false);\n const [ready, setReady] = useState(false);\n\n const { ref: iframeRef, element: iframeElement, width, height } = useElementSize();\n\n useEffect(() => {\n if (mounted) {\n dispatchPluginEvent(iframeElement as HTMLIFrameElement, {\n type: IFRAME_RESIZE,\n payload: {\n width,\n height,\n },\n }, url);\n }\n }, [iframeElement, mounted, width, height, url]);\n\n usePluginEvent(iframeElement, IFRAME_MOUNTED, () => {\n setMounted(true);\n });\n\n usePluginEvent(iframeElement, IFRAME_READY, () => {\n setReady(true);\n });\n\n const fallback = (\n <Spinner animation=\"border\" variant=\"light\" screenReaderText=\"Loading\" />\n );\n\n return (\n <>\n <iframe\n ref={iframeRef}\n title={title}\n src={url}\n allow={IFRAME_FEATURE_POLICY}\n referrerPolicy=\"origin\" // The sent referrer will be limited to the origin of the referring page: its scheme, host, and port.\n className={classNames(\n 'border border-0 w-100',\n { 'd-none': !ready },\n )}\n />\n {!ready && fallback}\n </>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../../../../runtime/slots/widget/iframe/hooks.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Hooks file for functions that handle the communication between a Plugin and its Host\n */\n\nimport {\n LegacyRef,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState\n} from 'react';\n\nimport { IFRAME_MOUNTED, IFRAME_READY, IFRAME_UNMOUNTED } from './constants';\nimport { MessageEventCallback } from './types';\n\n/* Listening for events */\n\n/**\n * Dynamically add an event listener to the provided source window.\n * The source window can be the global parent (ie. the \"window\" object in the browser)\n * or it can be the content window of an individual element (ie. iFrame plugin container)\n */\nexport function useMessageEvent(srcWindow: Window | null, type: string, callback: MessageEventCallback) {\n // useLayoutEffect is called before the browser repaints the screen\n useLayoutEffect(() => {\n // Create a listener callback function\n const listener = (event: MessageEvent<{ type: string, payload: any }>) => {\n // Filter messages to those from our source window.\n // NOTE: the \"srcWindow\" is determined by the below useHostEvent and usePluginEvent functions\n if (event.source === srcWindow) {\n // Fire callback if the type from the listened event matches the type from the message event\n if (event.data.type === type) {\n callback({ type, payload: event.data.payload });\n }\n }\n };\n // Add the listener to the global object if the srcWindow is not null\n if (srcWindow !== null) {\n global.addEventListener('message', listener);\n }\n // useEffect cleanup\n return () => {\n global.removeEventListener('message', listener);\n };\n }, [srcWindow, type, callback]);\n}\n\n/**\n * Called by the Plugin component to use events that were listened to (ie. PLUGIN_RESIZE)\n */\nexport function useHostEvent(type: string, callback: MessageEventCallback) {\n useMessageEvent(global.parent, type, callback);\n}\n\n/**\n * Used to listen for events from a wrapped Plugin element (eg. PluginContainerIframe)\n *\n * @param element - Plugin element (eg. <iframe>)\n * @param type - Event type (eg. PLUGIN_RESIZE)\n * @param callback - Function to call when the event is triggered\n */\nexport function usePluginEvent(element: HTMLIFrameElement | undefined, type: string, callback: MessageEventCallback) {\n const contentWindow = element ? element.contentWindow : null;\n useMessageEvent(contentWindow, type, callback);\n}\n\n/** Dispatching events */\n\n/**\n * Base dispatch function called by dispatchHostEvent and dispatchPluginEvent.\n * Uses the `postMessage` method to enable cross-origin communication between Window objects\n *\n * @param targetWindow - Window that the message event is being dispatched to\n * @param message - Data object for the message\n * @param targetOrigin - URL for the window that the message event is being dispatched from\n */\nexport function dispatchMessageEvent(targetWindow: Window | null, message: any, targetOrigin: string) {\n /** Checking targetOrigin falsiness here since '', null or undefined would all be\n * reasons not to try to post a message to the origin.\n */\n if (targetWindow && targetOrigin) {\n targetWindow.postMessage(message, targetOrigin);\n }\n}\n\n/**\n * Used to dispatch events for a Plugin\n *\n * @param element - Plugin element (eg. <iframe>)\n * @param message - Data object for the message\n * @param targetOrigin - URL for the window that the message event is being dispatched from\n */\nexport function dispatchPluginEvent(element: HTMLIFrameElement, message: any, targetOrigin: string) {\n dispatchMessageEvent(element.contentWindow, message, targetOrigin);\n}\n\n/**\n * Used to dispatch events for the Host\n *\n * @param message - Data object for the message\n */\nexport function dispatchHostEvent(message: any) {\n dispatchMessageEvent(global.parent, message, global.document.referrer);\n}\n\n// Called inside Plugin when 'ready' prop is true\nexport function dispatchReadyEvent() {\n dispatchHostEvent({ type: IFRAME_READY });\n}\n\n// Below mounted events are called in a useEffect inside Plugin with [] dependencies — https://react.dev/learn/synchronizing-with-effects\nexport function dispatchMountedEvent() {\n dispatchHostEvent({ type: IFRAME_MOUNTED });\n}\n\nexport function dispatchUnmountedEvent() {\n dispatchHostEvent({ type: IFRAME_UNMOUNTED });\n}\n\n/**\n * Used to determine the size of an element as it is being resized in the browser.\n * ResizeObserver (https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver) is used to maintain a reference to the element's content/border box.\n *\n * @returns Memoized value that contains a reference to the Plugin element (eg. iframe)\n */\nexport function useElementSize() {\n // Holds a reference to the ResizeObserver\n const observerRef = useRef<ResizeObserver | null>(null);\n\n const [dimensions, setDimensions] = useState({ width: 0, height: 0 });\n const [offset, setOffset] = useState({ x: 0, y: 0 });\n const [element, setElement] = useState<HTMLIFrameElement | undefined>();\n // Sets a reference to the Plugin element when passed to the Plugin element as a \"ref\" attribute (eg. <iframe>)\n const measuredRef: LegacyRef<HTMLIFrameElement> = useCallback(_element => {\n setElement(_element);\n }, []);\n\n useEffect(() => {\n // Create a new ResizeObserver\n observerRef.current = new ResizeObserver(() => {\n if (element) {\n // Set dimensions and any offset\n setDimensions({\n width: element.clientWidth,\n height: element.clientHeight,\n });\n setOffset({\n x: element.offsetLeft,\n y: element.offsetTop,\n });\n }\n });\n if (element) {\n // Tell the ResizeObserver to start watching the element — this enables the hook to detect resizing\n observerRef.current.observe(element);\n }\n }, [element]);\n\n return useMemo<{\n ref: LegacyRef<HTMLIFrameElement>,\n element: HTMLIFrameElement | undefined,\n width: number,\n height: number,\n x: number,\n y: number,\n }>(\n () => ({\n ref: measuredRef,\n element: element,\n width: dimensions.width,\n height: dimensions.height,\n x: offset.x,\n y: offset.y\n }),\n [measuredRef, element, dimensions, offset],\n );\n}\n"]}
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../../../../runtime/slots/widget/iframe/hooks.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Hooks file for functions that handle the communication between a Plugin and its Host\n */\n\nimport {\n LegacyRef,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState\n} from 'react';\n\nimport { IFRAME_MOUNTED, IFRAME_READY, IFRAME_UNMOUNTED } from './constants';\nimport { MessageEventCallback } from './types';\n\n/* Listening for events */\n\n/**\n * Dynamically add an event listener to the provided source window.\n * The source window can be the global parent (ie. the \"window\" object in the browser)\n * or it can be the content window of an individual element (ie. iFrame plugin container)\n */\nexport function useMessageEvent(srcWindow: Window | null, type: string, callback: MessageEventCallback) {\n // useLayoutEffect is called before the browser repaints the screen\n useLayoutEffect(() => {\n // Create a listener callback function\n const listener = (event: MessageEvent<{ type: string; payload: any }>) => {\n // Filter messages to those from our source window.\n // NOTE: the \"srcWindow\" is determined by the below useHostEvent and usePluginEvent functions\n if (event.source === srcWindow) {\n // Fire callback if the type from the listened event matches the type from the message event\n if (event.data.type === type) {\n callback({ type, payload: event.data.payload });\n }\n }\n };\n // Add the listener to the global object if the srcWindow is not null\n if (srcWindow !== null) {\n global.addEventListener('message', listener);\n }\n // useEffect cleanup\n return () => {\n global.removeEventListener('message', listener);\n };\n }, [srcWindow, type, callback]);\n}\n\n/**\n * Called by the Plugin component to use events that were listened to (ie. PLUGIN_RESIZE)\n */\nexport function useHostEvent(type: string, callback: MessageEventCallback) {\n useMessageEvent(global.parent, type, callback);\n}\n\n/**\n * Used to listen for events from a wrapped Plugin element (eg. PluginContainerIframe)\n *\n * @param element - Plugin element (eg. <iframe>)\n * @param type - Event type (eg. PLUGIN_RESIZE)\n * @param callback - Function to call when the event is triggered\n */\nexport function usePluginEvent(element: HTMLIFrameElement | undefined, type: string, callback: MessageEventCallback) {\n const contentWindow = element ? element.contentWindow : null;\n useMessageEvent(contentWindow, type, callback);\n}\n\n/** Dispatching events */\n\n/**\n * Base dispatch function called by dispatchHostEvent and dispatchPluginEvent.\n * Uses the `postMessage` method to enable cross-origin communication between Window objects\n *\n * @param targetWindow - Window that the message event is being dispatched to\n * @param message - Data object for the message\n * @param targetOrigin - URL for the window that the message event is being dispatched from\n */\nexport function dispatchMessageEvent(targetWindow: Window | null, message: any, targetOrigin: string) {\n /** Checking targetOrigin falsiness here since '', null or undefined would all be\n * reasons not to try to post a message to the origin.\n */\n if (targetWindow && targetOrigin) {\n targetWindow.postMessage(message, targetOrigin);\n }\n}\n\n/**\n * Used to dispatch events for a Plugin\n *\n * @param element - Plugin element (eg. <iframe>)\n * @param message - Data object for the message\n * @param targetOrigin - URL for the window that the message event is being dispatched from\n */\nexport function dispatchPluginEvent(element: HTMLIFrameElement, message: any, targetOrigin: string) {\n dispatchMessageEvent(element.contentWindow, message, targetOrigin);\n}\n\n/**\n * Used to dispatch events for the Host\n *\n * @param message - Data object for the message\n */\nexport function dispatchHostEvent(message: any) {\n dispatchMessageEvent(global.parent, message, global.document.referrer);\n}\n\n// Called inside Plugin when 'ready' prop is true\nexport function dispatchReadyEvent() {\n dispatchHostEvent({ type: IFRAME_READY });\n}\n\n// Below mounted events are called in a useEffect inside Plugin with [] dependencies — https://react.dev/learn/synchronizing-with-effects\nexport function dispatchMountedEvent() {\n dispatchHostEvent({ type: IFRAME_MOUNTED });\n}\n\nexport function dispatchUnmountedEvent() {\n dispatchHostEvent({ type: IFRAME_UNMOUNTED });\n}\n\n/**\n * Used to determine the size of an element as it is being resized in the browser.\n * ResizeObserver (https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver) is used to maintain a reference to the element's content/border box.\n *\n * @returns Memoized value that contains a reference to the Plugin element (eg. iframe)\n */\nexport function useElementSize() {\n // Holds a reference to the ResizeObserver\n const observerRef = useRef<ResizeObserver | null>(null);\n\n const [dimensions, setDimensions] = useState({ width: 0, height: 0 });\n const [offset, setOffset] = useState({ x: 0, y: 0 });\n const [element, setElement] = useState<HTMLIFrameElement | undefined>();\n // Sets a reference to the Plugin element when passed to the Plugin element as a \"ref\" attribute (eg. <iframe>)\n const measuredRef: LegacyRef<HTMLIFrameElement> = useCallback(_element => {\n setElement(_element);\n }, []);\n\n useEffect(() => {\n // Create a new ResizeObserver\n observerRef.current = new ResizeObserver(() => {\n if (element) {\n // Set dimensions and any offset\n setDimensions({\n width: element.clientWidth,\n height: element.clientHeight,\n });\n setOffset({\n x: element.offsetLeft,\n y: element.offsetTop,\n });\n }\n });\n if (element) {\n // Tell the ResizeObserver to start watching the element — this enables the hook to detect resizing\n observerRef.current.observe(element);\n }\n }, [element]);\n\n return useMemo<{\n ref: LegacyRef<HTMLIFrameElement>;\n element: HTMLIFrameElement | undefined;\n width: number;\n height: number;\n x: number;\n y: number;\n }>(\n () => ({\n ref: measuredRef,\n element: element,\n width: dimensions.width,\n height: dimensions.height,\n x: offset.x,\n y: offset.y\n }),\n [measuredRef, element, dimensions, offset],\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../runtime/slots/widget/iframe/types.ts"],"names":[],"mappings":"AAMA,CAAC","sourcesContent":["export interface MessageEventCallbackParams {\n type: string,\n payload: any,\n}\n\nexport type MessageEventCallback = ({ type, payload }: MessageEventCallbackParams) => void;\n;\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../runtime/slots/widget/iframe/types.ts"],"names":[],"mappings":"AAMA,CAAC","sourcesContent":["export interface MessageEventCallbackParams {\n type: string;\n payload: any;\n}\n\nexport type MessageEventCallback = ({ type, payload }: MessageEventCallbackParams) => void;\n;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../runtime/slots/widget/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,MAAM,CAAN,IAAY,oBAmCX;AAnCD,WAAY,oBAAoB;IAC9B;;OAEG;IACH,+CAAuB,CAAA;IAEvB;;OAEG;IACH,iDAAyB,CAAA;IAEzB;;OAEG;IACH,0DAAkC,CAAA;IAElC;;OAEG;IACH,4DAAoC,CAAA;IAEpC;;OAEG;IACH,iDAAyB,CAAA;IAEzB;;OAEG;IACH,+CAAuB,CAAA;IAEvB;;OAEG;IACH,iDAAyB,CAAA;AAC3B,CAAC,EAnCW,oBAAoB,KAApB,oBAAoB,QAmC/B","sourcesContent":["/**\n * Base UI Widget Operations\n *\n * \"Widget\" operations are a sub-type of UI operations which allow manipulation of the list of widgets (UI components) loaded into the slot. Widget operations are divided further into two sub-types: absolute and relative.\n *\n * Absolute widget operations allow simple list operations like appending and prepending which don't depend on any other list elements.\n *\n * Relative widget operations depend on a relationship to some other list element, such as \"insert before\" and \"insert after\". Some affect those elements, some add something to the list near them.\n */\n\nimport { ReactNode } from 'react';\nimport { BaseSlotOperation } from '../types';\n\nexport enum WidgetOperationTypes {\n /**\n * Adds a widget to the end of the slot's list of widgets.\n */\n APPEND = 'widgetAppend',\n\n /**\n * Adds a widget to the beginning of the slot's list of widgets.\n */\n PREPEND = 'widgetPrepend',\n\n /**\n * Adds a widget after the specified widget ID. Multiple \"insert after\" operations on the same widget ID occur in the order they were declared.\n */\n INSERT_AFTER = 'widgetInsertAfter',\n\n /**\n * Adds a widget before the specified widget ID. Multiple \"insert after\" operations on the same widget ID occur in the order they were declared.\n */\n INSERT_BEFORE = 'widgetInsertBefore',\n\n /**\n * Removes the specified widget ID and adds a widget in its place. Multiple \"replace\" operations on the same widget ID occur in the order they were declared, and only the first will succeed unless the new widget's ID is the same as the one that was removed.\n */\n REPLACE = 'widgetReplace',\n\n /**\n * Removes the specified widget ID from the slot's list of widgets. Subsequent relative widget operations on that widget ID will not be applied.\n */\n REMOVE = 'widgetRemove',\n\n /**\n * Provides options to the specified widget ID. Multiple \"options\" operations on the same widget ID will merge with and override any duplicate properties in the options object - last one in wins.\n */\n OPTIONS = 'widgetOptions',\n}\n\nexport type AbsoluteWidgetOperationTypes = WidgetOperationTypes.APPEND | WidgetOperationTypes.PREPEND;\n\nexport type RelativeWidgetOperationTypes = WidgetOperationTypes.INSERT_AFTER | WidgetOperationTypes.INSERT_BEFORE | WidgetOperationTypes.REPLACE | WidgetOperationTypes.OPTIONS;\n\nexport interface BaseWidgetOperation extends BaseSlotOperation {\n op: WidgetOperationTypes,\n}\n\n// Widget renderer props\n\nexport interface WidgetComponentProps {\n component: React.ComponentType,\n}\n\nexport interface WidgetElementProps {\n element: ReactNode,\n}\n\nexport interface WidgetIFrameProps {\n url: string,\n title: string,\n}\n\nexport type WidgetRendererProps = (\n WidgetComponentProps | WidgetElementProps | WidgetIFrameProps\n);\n\nexport interface WidgetIdentityProps {\n id: string,\n role?: string,\n}\n\nexport interface WidgetRelationshipProps {\n relatedId: string,\n}\n\n// Concrete UI Widget Operations\n\nexport type WidgetAppendOperation = BaseWidgetOperation & WidgetIdentityProps & WidgetRendererProps & {\n op: WidgetOperationTypes.APPEND,\n};\n\nexport type WidgetPrependOperation = BaseWidgetOperation & WidgetIdentityProps & WidgetRendererProps & {\n op: WidgetOperationTypes.PREPEND,\n};\n\nexport type WidgetInsertAfterOperation = BaseWidgetOperation & WidgetIdentityProps & WidgetRendererProps & WidgetRelationshipProps & {\n op: WidgetOperationTypes.INSERT_AFTER,\n};\n\nexport type WidgetInsertBeforeOperation = BaseWidgetOperation & WidgetIdentityProps & WidgetRendererProps & WidgetRelationshipProps & {\n op: WidgetOperationTypes.INSERT_BEFORE,\n};\n\nexport type WidgetRemoveOperation = BaseWidgetOperation & WidgetRelationshipProps & {\n op: WidgetOperationTypes.REMOVE,\n};\n\nexport type WidgetOptionsOperation = BaseWidgetOperation & WidgetRelationshipProps & {\n op: WidgetOperationTypes.OPTIONS,\n options: Record<string, unknown>,\n};\n\nexport type WidgetReplaceOperation = BaseWidgetOperation & WidgetIdentityProps & WidgetRendererProps & WidgetRelationshipProps & { op: WidgetOperationTypes.REPLACE };\n\nexport type WidgetAbsoluteOperation = WidgetAppendOperation | WidgetPrependOperation;\n\nexport type WidgetRelativeRendererOperation = WidgetInsertAfterOperation | WidgetInsertBeforeOperation | WidgetReplaceOperation;\n\nexport type WidgetRelativeOperation = WidgetRelativeRendererOperation | WidgetRemoveOperation | WidgetOptionsOperation;\n\nexport type WidgetRendererOperation = WidgetAbsoluteOperation | WidgetRelativeRendererOperation;\n\nexport type WidgetOperation = WidgetAbsoluteOperation | WidgetRelativeOperation;\n\n/**\n * An identified widget is a simple data structure to associate an ID with a ReactNode so we can\n * apply widget operations to our list of widgets. It helps us find a ReactNode with a particular\n * ID for relative widget operations.\n */\nexport interface IdentifiedWidget {\n id: string,\n role?: string,\n node: ReactNode,\n}\n\nexport interface WidgetList extends Array<ReactNode> {\n identified: IdentifiedWidget[],\n byId(id: string): ReactNode[],\n withoutId(id: string): ReactNode[],\n byRole(role: string): ReactNode[],\n withoutRole(role: string): ReactNode[],\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../runtime/slots/widget/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,MAAM,CAAN,IAAY,oBAmCX;AAnCD,WAAY,oBAAoB;IAC9B;;OAEG;IACH,+CAAuB,CAAA;IAEvB;;OAEG;IACH,iDAAyB,CAAA;IAEzB;;OAEG;IACH,0DAAkC,CAAA;IAElC;;OAEG;IACH,4DAAoC,CAAA;IAEpC;;OAEG;IACH,iDAAyB,CAAA;IAEzB;;OAEG;IACH,+CAAuB,CAAA;IAEvB;;OAEG;IACH,iDAAyB,CAAA;AAC3B,CAAC,EAnCW,oBAAoB,KAApB,oBAAoB,QAmC/B","sourcesContent":["/**\n * Base UI Widget Operations\n *\n * \"Widget\" operations are a sub-type of UI operations which allow manipulation of the list of widgets (UI components) loaded into the slot. Widget operations are divided further into two sub-types: absolute and relative.\n *\n * Absolute widget operations allow simple list operations like appending and prepending which don't depend on any other list elements.\n *\n * Relative widget operations depend on a relationship to some other list element, such as \"insert before\" and \"insert after\". Some affect those elements, some add something to the list near them.\n */\n\nimport { ReactNode } from 'react';\nimport { BaseSlotOperation } from '../types';\n\nexport enum WidgetOperationTypes {\n /**\n * Adds a widget to the end of the slot's list of widgets.\n */\n APPEND = 'widgetAppend',\n\n /**\n * Adds a widget to the beginning of the slot's list of widgets.\n */\n PREPEND = 'widgetPrepend',\n\n /**\n * Adds a widget after the specified widget ID. Multiple \"insert after\" operations on the same widget ID occur in the order they were declared.\n */\n INSERT_AFTER = 'widgetInsertAfter',\n\n /**\n * Adds a widget before the specified widget ID. Multiple \"insert after\" operations on the same widget ID occur in the order they were declared.\n */\n INSERT_BEFORE = 'widgetInsertBefore',\n\n /**\n * Removes the specified widget ID and adds a widget in its place. Multiple \"replace\" operations on the same widget ID occur in the order they were declared, and only the first will succeed unless the new widget's ID is the same as the one that was removed.\n */\n REPLACE = 'widgetReplace',\n\n /**\n * Removes the specified widget ID from the slot's list of widgets. Subsequent relative widget operations on that widget ID will not be applied.\n */\n REMOVE = 'widgetRemove',\n\n /**\n * Provides options to the specified widget ID. Multiple \"options\" operations on the same widget ID will merge with and override any duplicate properties in the options object - last one in wins.\n */\n OPTIONS = 'widgetOptions',\n}\n\nexport type AbsoluteWidgetOperationTypes = WidgetOperationTypes.APPEND | WidgetOperationTypes.PREPEND;\n\nexport type RelativeWidgetOperationTypes = WidgetOperationTypes.INSERT_AFTER | WidgetOperationTypes.INSERT_BEFORE | WidgetOperationTypes.REPLACE | WidgetOperationTypes.OPTIONS;\n\nexport interface BaseWidgetOperation extends BaseSlotOperation {\n op: WidgetOperationTypes;\n}\n\n// Widget renderer props\n\nexport interface WidgetComponentProps {\n component: React.ComponentType;\n}\n\nexport interface WidgetElementProps {\n element: ReactNode;\n}\n\nexport interface WidgetIFrameProps {\n url: string;\n title: string;\n}\n\nexport type WidgetRendererProps = (\n WidgetComponentProps | WidgetElementProps | WidgetIFrameProps\n);\n\nexport interface WidgetIdentityProps {\n id: string;\n role?: string;\n}\n\nexport interface WidgetRelationshipProps {\n relatedId: string;\n}\n\n// Concrete UI Widget Operations\n\nexport type WidgetAppendOperation = BaseWidgetOperation & WidgetIdentityProps & WidgetRendererProps & {\n op: WidgetOperationTypes.APPEND;\n};\n\nexport type WidgetPrependOperation = BaseWidgetOperation & WidgetIdentityProps & WidgetRendererProps & {\n op: WidgetOperationTypes.PREPEND;\n};\n\nexport type WidgetInsertAfterOperation = BaseWidgetOperation & WidgetIdentityProps & WidgetRendererProps & WidgetRelationshipProps & {\n op: WidgetOperationTypes.INSERT_AFTER;\n};\n\nexport type WidgetInsertBeforeOperation = BaseWidgetOperation & WidgetIdentityProps & WidgetRendererProps & WidgetRelationshipProps & {\n op: WidgetOperationTypes.INSERT_BEFORE;\n};\n\nexport type WidgetRemoveOperation = BaseWidgetOperation & WidgetRelationshipProps & {\n op: WidgetOperationTypes.REMOVE;\n};\n\nexport type WidgetOptionsOperation = BaseWidgetOperation & WidgetRelationshipProps & {\n op: WidgetOperationTypes.OPTIONS;\n options: Record<string, unknown>;\n};\n\nexport type WidgetReplaceOperation = BaseWidgetOperation & WidgetIdentityProps & WidgetRendererProps & WidgetRelationshipProps & { op: WidgetOperationTypes.REPLACE };\n\nexport type WidgetAbsoluteOperation = WidgetAppendOperation | WidgetPrependOperation;\n\nexport type WidgetRelativeRendererOperation = WidgetInsertAfterOperation | WidgetInsertBeforeOperation | WidgetReplaceOperation;\n\nexport type WidgetRelativeOperation = WidgetRelativeRendererOperation | WidgetRemoveOperation | WidgetOptionsOperation;\n\nexport type WidgetRendererOperation = WidgetAbsoluteOperation | WidgetRelativeRendererOperation;\n\nexport type WidgetOperation = WidgetAbsoluteOperation | WidgetRelativeOperation;\n\n/**\n * An identified widget is a simple data structure to associate an ID with a ReactNode so we can\n * apply widget operations to our list of widgets. It helps us find a ReactNode with a particular\n * ID for relative widget operations.\n */\nexport interface IdentifiedWidget {\n id: string;\n role?: string;\n node: ReactNode;\n}\n\nexport interface WidgetList extends Array<ReactNode> {\n identified: IdentifiedWidget[];\n byId(id: string): ReactNode[];\n withoutId(id: string): ReactNode[];\n byRole(role: string): ReactNode[];\n withoutRole(role: string): ReactNode[];\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"initializeMockApp.js","sourceRoot":"","sources":["../../../runtime/testing/initializeMockApp.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,aAAa,CAAC;AAIrC,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAE1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,EACxC,QAAQ,GAAG,YAAY,EACvB,iBAAiB,GAAG,IAAI,MAItB,EAAE;IACJ,MAAM,MAAM,GAAG,UAAU,CAAC;IAC1B,eAAe,CAAC,MAAM,CAAC,CAAC;IAExB,MAAM,cAAc,GAAG,gBAAgB,CAAC,kBAAkB,EAAE;QAC1D,MAAM,EAAE,aAAa,EAAE;KACxB,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,aAAa,CAAC,eAAe,EAAE;QACjD,MAAM,EAAE,aAAa,EAAE;QACvB,cAAc;KACf,CAAC,CAAC;IAEH,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;IAExC,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,oBAAoB,EAAE;QAChE,MAAM,EAAE,aAAa,EAAE;QACvB,UAAU,EAAE,WAAW,CAAC,0BAA0B,EAAE;QACpD,cAAc;KACf,CAAC,CAAC;IAEH,kGAAkG;IAClG,aAAa,CAAC;QACZ,QAAQ;KACT,CAAC,CAAC;IAEH,OAAO;QACL,gBAAgB;QAChB,WAAW;QACX,cAAc;KACf,CAAC;AACJ,CAAC","sourcesContent":["import siteConfig from 'site.config';\n\nimport { LocalizedMessages, User } from '../../types';\n\nimport { configureAnalytics, MockAnalyticsService } from '../analytics';\nimport { configureAuth, MockAuthService, setAuthenticatedUser } from '../auth';\nimport { getSiteConfig, mergeSiteConfig } from '../config';\nimport { configureI18n } from '../i18n';\nimport { configureLogging, MockLoggingService } from '../logging';\nimport mockMessages from './mockMessages';\n\n/**\n * Initializes a mock application for component testing. The mock application includes\n * mock analytics, auth, and logging services, and the real i18n service.\n *\n * See MockAnalyticsService, MockAuthService, and MockLoggingService for mock implementation\n * details. For the most part, the analytics and logging services just implement their functions\n * with jest.fn() and do nothing else, whereas the MockAuthService actually has some behavior\n * implemented, it just doesn't make any HTTP calls.\n *\n * Note that this mock application is not sufficient for testing the full application lifecycle or\n * initialization callbacks/custom handlers as described in the 'initialize' function's\n * documentation. It exists merely to set up the mock services that components themselves tend to\n * interact with most often. It could be extended to allow for setting up custom handlers fairly\n * easily, as this functionality would be more-or-less identical to what the real initialize\n * function does.\n *\n * Example:\n *\n * ```\n * import { initializeMockApp, logInfo } from '@openedx/frontend-base';\n *\n * describe('initializeMockApp', () => {\n * it('mocks things correctly', () => {\n * const { loggingService } = initializeMockApp();\n * logInfo('test', {});\n * expect(loggingService.logInfo).toHaveBeenCalledWith('test', {});\n * });\n * });\n * ```\n *\n * @param {Object} [options]\n * @param {*} [options.messages] A i18n-compatible messages object, or an array of such objects. If\n * an array is provided, duplicate keys are resolved with the last-one-in winning.\n * @param {UserData|null} [options.authenticatedUser] A UserData object representing the\n * authenticated user. This is passed directly to MockAuthService.\n * @memberof module:Testing\n */\nexport default function initializeMockApp({\n messages = mockMessages,\n authenticatedUser = null,\n}: {\n messages?: LocalizedMessages,\n authenticatedUser?: User | null,\n} = {}) {\n const config = siteConfig;\n mergeSiteConfig(config);\n\n const loggingService = configureLogging(MockLoggingService, {\n config: getSiteConfig(),\n });\n\n const authService = configureAuth(MockAuthService, {\n config: getSiteConfig(),\n loggingService,\n });\n\n setAuthenticatedUser(authenticatedUser);\n\n const analyticsService = configureAnalytics(MockAnalyticsService, {\n config: getSiteConfig(),\n httpClient: authService.getAuthenticatedHttpClient(),\n loggingService,\n });\n\n // The i18n service configureI18n function has no return value, since there isn't a service class.\n configureI18n({\n messages,\n });\n\n return {\n analyticsService,\n authService,\n loggingService,\n };\n}\n"]}
1
+ {"version":3,"file":"initializeMockApp.js","sourceRoot":"","sources":["../../../runtime/testing/initializeMockApp.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,aAAa,CAAC;AAIrC,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAE1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,EACxC,QAAQ,GAAG,YAAY,EACvB,iBAAiB,GAAG,IAAI,MAItB,EAAE;IACJ,MAAM,MAAM,GAAG,UAAU,CAAC;IAC1B,eAAe,CAAC,MAAM,CAAC,CAAC;IAExB,MAAM,cAAc,GAAG,gBAAgB,CAAC,kBAAkB,EAAE;QAC1D,MAAM,EAAE,aAAa,EAAE;KACxB,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,aAAa,CAAC,eAAe,EAAE;QACjD,MAAM,EAAE,aAAa,EAAE;QACvB,cAAc;KACf,CAAC,CAAC;IAEH,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;IAExC,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,oBAAoB,EAAE;QAChE,MAAM,EAAE,aAAa,EAAE;QACvB,UAAU,EAAE,WAAW,CAAC,0BAA0B,EAAE;QACpD,cAAc;KACf,CAAC,CAAC;IAEH,kGAAkG;IAClG,aAAa,CAAC;QACZ,QAAQ;KACT,CAAC,CAAC;IAEH,OAAO;QACL,gBAAgB;QAChB,WAAW;QACX,cAAc;KACf,CAAC;AACJ,CAAC","sourcesContent":["import siteConfig from 'site.config';\n\nimport { LocalizedMessages, User } from '../../types';\n\nimport { configureAnalytics, MockAnalyticsService } from '../analytics';\nimport { configureAuth, MockAuthService, setAuthenticatedUser } from '../auth';\nimport { getSiteConfig, mergeSiteConfig } from '../config';\nimport { configureI18n } from '../i18n';\nimport { configureLogging, MockLoggingService } from '../logging';\nimport mockMessages from './mockMessages';\n\n/**\n * Initializes a mock application for component testing. The mock application includes\n * mock analytics, auth, and logging services, and the real i18n service.\n *\n * See MockAnalyticsService, MockAuthService, and MockLoggingService for mock implementation\n * details. For the most part, the analytics and logging services just implement their functions\n * with jest.fn() and do nothing else, whereas the MockAuthService actually has some behavior\n * implemented, it just doesn't make any HTTP calls.\n *\n * Note that this mock application is not sufficient for testing the full application lifecycle or\n * initialization callbacks/custom handlers as described in the 'initialize' function's\n * documentation. It exists merely to set up the mock services that components themselves tend to\n * interact with most often. It could be extended to allow for setting up custom handlers fairly\n * easily, as this functionality would be more-or-less identical to what the real initialize\n * function does.\n *\n * Example:\n *\n * ```\n * import { initializeMockApp, logInfo } from '@openedx/frontend-base';\n *\n * describe('initializeMockApp', () => {\n * it('mocks things correctly', () => {\n * const { loggingService } = initializeMockApp();\n * logInfo('test', {});\n * expect(loggingService.logInfo).toHaveBeenCalledWith('test', {});\n * });\n * });\n * ```\n *\n * @param {Object} [options]\n * @param {*} [options.messages] A i18n-compatible messages object, or an array of such objects. If\n * an array is provided, duplicate keys are resolved with the last-one-in winning.\n * @param {UserData|null} [options.authenticatedUser] A UserData object representing the\n * authenticated user. This is passed directly to MockAuthService.\n * @memberof module:Testing\n */\nexport default function initializeMockApp({\n messages = mockMessages,\n authenticatedUser = null,\n}: {\n messages?: LocalizedMessages;\n authenticatedUser?: User | null;\n} = {}) {\n const config = siteConfig;\n mergeSiteConfig(config);\n\n const loggingService = configureLogging(MockLoggingService, {\n config: getSiteConfig(),\n });\n\n const authService = configureAuth(MockAuthService, {\n config: getSiteConfig(),\n loggingService,\n });\n\n setAuthenticatedUser(authenticatedUser);\n\n const analyticsService = configureAnalytics(MockAnalyticsService, {\n config: getSiteConfig(),\n httpClient: authService.getAuthenticatedHttpClient(),\n loggingService,\n });\n\n // The i18n service configureI18n function has no return value, since there isn't a service class.\n configureI18n({\n messages,\n });\n\n return {\n analyticsService,\n authService,\n loggingService,\n };\n}\n"]}
@@ -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;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"]}
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"]}
@@ -1 +1 @@
1
- {"version":3,"file":"BarContext.js","sourceRoot":"","sources":["../../../../shell/dev/devHeader/BarContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA4B,MAAM,OAAO,CAAC;AAK/D,CAAC;AAEF,MAAM,UAAU,GAAG,aAAa,CAAsB;IACpD,GAAG,EAAE,EAAE;IACP,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC;CAClB,CAAC,CAAC;AAEH,eAAe,UAAU,CAAC","sourcesContent":["import { createContext, Dispatch, SetStateAction } from 'react';\n\ninterface BarContextInterface {\n bar: string,\n setBar: Dispatch<SetStateAction<string>>,\n};\n\nconst BarContext = createContext<BarContextInterface>({\n bar: '',\n setBar: () => { }\n});\n\nexport default BarContext;\n"]}
1
+ {"version":3,"file":"BarContext.js","sourceRoot":"","sources":["../../../../shell/dev/devHeader/BarContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA4B,MAAM,OAAO,CAAC;AAK/D,CAAC;AAEF,MAAM,UAAU,GAAG,aAAa,CAAsB;IACpD,GAAG,EAAE,EAAE;IACP,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC;CAClB,CAAC,CAAC;AAEH,eAAe,UAAU,CAAC","sourcesContent":["import { createContext, Dispatch, SetStateAction } from 'react';\n\ninterface BarContextInterface {\n bar: string;\n setBar: Dispatch<SetStateAction<string>>;\n};\n\nconst BarContext = createContext<BarContextInterface>({\n bar: '',\n setBar: () => { }\n});\n\nexport default BarContext;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"BarProvider.js","sourceRoot":"","sources":["../../../../shell/dev/devHeader/BarProvider.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAa,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACrD,OAAO,UAAU,MAAM,cAAc,CAAC;AAEtC,SAAS,MAAM;IACb,OAAO,KAAK,CAAC;AACf,CAAC;AAMD,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAAE,QAAQ,EAAoB;IAChE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAEzC,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACrC,GAAG;QACH,MAAM;KACP,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;IAEnB,OAAO,CACL,KAAC,UAAU,CAAC,QAAQ,IAAC,KAAK,EAAE,eAAe,YACxC,QAAQ,GACW,CACvB,CAAC;AACJ,CAAC;AAAA,CAAC","sourcesContent":["import { ReactNode, useMemo, useState } from 'react';\nimport BarContext from './BarContext';\n\nfunction getBar() {\n return 'Bar';\n}\n\ninterface BarProviderProps {\n children?: ReactNode,\n}\n\nexport default function BarProvider({ children }: BarProviderProps) {\n const [bar, setBar] = useState(getBar());\n\n const barContextValue = useMemo(() => ({\n bar,\n setBar,\n }), [bar, setBar]);\n\n return (\n <BarContext.Provider value={barContextValue}>\n {children}\n </BarContext.Provider>\n );\n};\n"]}
1
+ {"version":3,"file":"BarProvider.js","sourceRoot":"","sources":["../../../../shell/dev/devHeader/BarProvider.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAa,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACrD,OAAO,UAAU,MAAM,cAAc,CAAC;AAEtC,SAAS,MAAM;IACb,OAAO,KAAK,CAAC;AACf,CAAC;AAMD,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAAE,QAAQ,EAAoB;IAChE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAEzC,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACrC,GAAG;QACH,MAAM;KACP,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;IAEnB,OAAO,CACL,KAAC,UAAU,CAAC,QAAQ,IAAC,KAAK,EAAE,eAAe,YACxC,QAAQ,GACW,CACvB,CAAC;AACJ,CAAC;AAAA,CAAC","sourcesContent":["import { ReactNode, useMemo, useState } from 'react';\nimport BarContext from './BarContext';\n\nfunction getBar() {\n return 'Bar';\n}\n\ninterface BarProviderProps {\n children?: ReactNode;\n}\n\nexport default function BarProvider({ children }: BarProviderProps) {\n const [bar, setBar] = useState(getBar());\n\n const barContextValue = useMemo(() => ({\n bar,\n setBar,\n }), [bar, setBar]);\n\n return (\n <BarContext.Provider value={barContextValue}>\n {children}\n </BarContext.Provider>\n );\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"FooContext.js","sourceRoot":"","sources":["../../../../shell/dev/devHeader/FooContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA4B,MAAM,OAAO,CAAC;AAK/D,CAAC;AAEF,MAAM,UAAU,GAAG,aAAa,CAAsB;IACpD,GAAG,EAAE,EAAE;IACP,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC;CAClB,CAAC,CAAC;AAEH,eAAe,UAAU,CAAC","sourcesContent":["import { createContext, Dispatch, SetStateAction } from 'react';\n\ninterface FooContextInterface {\n foo: string,\n setFoo: Dispatch<SetStateAction<string>>,\n};\n\nconst FooContext = createContext<FooContextInterface>({\n foo: '',\n setFoo: () => { }\n});\n\nexport default FooContext;\n"]}
1
+ {"version":3,"file":"FooContext.js","sourceRoot":"","sources":["../../../../shell/dev/devHeader/FooContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA4B,MAAM,OAAO,CAAC;AAK/D,CAAC;AAEF,MAAM,UAAU,GAAG,aAAa,CAAsB;IACpD,GAAG,EAAE,EAAE;IACP,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC;CAClB,CAAC,CAAC;AAEH,eAAe,UAAU,CAAC","sourcesContent":["import { createContext, Dispatch, SetStateAction } from 'react';\n\ninterface FooContextInterface {\n foo: string;\n setFoo: Dispatch<SetStateAction<string>>;\n};\n\nconst FooContext = createContext<FooContextInterface>({\n foo: '',\n setFoo: () => { }\n});\n\nexport default FooContext;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"FooProvider.js","sourceRoot":"","sources":["../../../../shell/dev/devHeader/FooProvider.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAa,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACrD,OAAO,UAAU,MAAM,cAAc,CAAC;AAEtC,SAAS,MAAM;IACb,OAAO,KAAK,CAAC;AACf,CAAC;AAMD,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAAE,QAAQ,EAAoB;IAChE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAEzC,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACrC,GAAG;QACH,MAAM;KACP,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;IAEnB,OAAO,CACL,KAAC,UAAU,CAAC,QAAQ,IAAC,KAAK,EAAE,eAAe,YACxC,QAAQ,GACW,CACvB,CAAC;AACJ,CAAC;AAAA,CAAC","sourcesContent":["import { ReactNode, useMemo, useState } from 'react';\nimport FooContext from './FooContext';\n\nfunction getFoo() {\n return 'Foo';\n}\n\ninterface FooProviderProps {\n children?: ReactNode,\n}\n\nexport default function FooProvider({ children }: FooProviderProps) {\n const [foo, setFoo] = useState(getFoo());\n\n const fooContextValue = useMemo(() => ({\n foo,\n setFoo,\n }), [foo, setFoo]);\n\n return (\n <FooContext.Provider value={fooContextValue}>\n {children}\n </FooContext.Provider>\n );\n};\n"]}
1
+ {"version":3,"file":"FooProvider.js","sourceRoot":"","sources":["../../../../shell/dev/devHeader/FooProvider.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAa,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACrD,OAAO,UAAU,MAAM,cAAc,CAAC;AAEtC,SAAS,MAAM;IACb,OAAO,KAAK,CAAC;AACf,CAAC;AAMD,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAAE,QAAQ,EAAoB;IAChE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAEzC,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACrC,GAAG;QACH,MAAM;KACP,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;IAEnB,OAAO,CACL,KAAC,UAAU,CAAC,QAAQ,IAAC,KAAK,EAAE,eAAe,YACxC,QAAQ,GACW,CACvB,CAAC;AACJ,CAAC;AAAA,CAAC","sourcesContent":["import { ReactNode, useMemo, useState } from 'react';\nimport FooContext from './FooContext';\n\nfunction getFoo() {\n return 'Foo';\n}\n\ninterface FooProviderProps {\n children?: ReactNode;\n}\n\nexport default function FooProvider({ children }: FooProviderProps) {\n const [foo, setFoo] = useState(getFoo());\n\n const fooContextValue = useMemo(() => ({\n foo,\n setFoo,\n }), [foo, setFoo]);\n\n return (\n <FooContext.Provider value={fooContextValue}>\n {children}\n </FooContext.Provider>\n );\n};\n"]}
@@ -1 +1 @@
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&apos;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 &quot;Bar&quot;.</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 &quot;highlighted&quot; 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
+ {"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&apos;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 &quot;Bar&quot;.</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 &quot;highlighted&quot; 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 +1 @@
1
- {"version":3,"file":"app.js","sourceRoot":"","sources":["../../../../shell/dev/slotShowcase/app.tsx"],"names":[],"mappings":"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","sourcesContent":["import { NavDropdownMenuSlot } from '../..';\nimport LinkMenuItem from '../../menus/LinkMenuItem';\nimport { LayoutOperationTypes, WidgetOperationTypes, useSlotContext } from '../../../runtime';\nimport { App } from '../../../types';\nimport HorizontalSlotLayout from './HorizontalSlotLayout';\nimport SlotShowcasePage from './SlotShowcasePage';\nimport WidgetWithOptions from './WidgetWithOptions';\n\nfunction Widget({ title, op, className, ...props }: { title: string, op?: string, className?: string } & Record<string, unknown>) {\n return (\n <div className={`showcase-widget ${className ?? ''}`} {...props}>\n {title}\n {op && (\n <span>{' '}(<code>{op}</code>)</span>\n )}\n </div>\n );\n}\n\nfunction TakesProps({ aSlotProp }: { aSlotProp: string }) {\n return (\n <div className=\"showcase-widget\">And this is a slot prop that was passed down via props: <code>{aSlotProp}</code></div>\n );\n}\n\nfunction TakesPropsViaContext() {\n const slotContext = useSlotContext();\n const aSlotProp = typeof slotContext.aSlotProp === 'string' ? slotContext.aSlotProp : 'foo';\n return (\n <div className=\"showcase-widget\">And this is the same prop, but accessed via slot context: <code>{aSlotProp}</code></div>\n );\n}\n\nconst app: App = {\n appId: 'org.openedx.frontend.app.slotShowcase',\n routes: [{\n id: 'org.openedx.frontend.route.slotShowcase',\n path: '/slots',\n Component: SlotShowcasePage,\n handle: {\n roles: ['org.openedx.frontend.role.slotShowcase'],\n }\n }],\n slots: [\n // Simple\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseSimple',\n id: 'org.openedx.frontend.widget.slotShowcase.simpleChild1',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget One\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseSimple',\n id: 'org.openedx.frontend.widget.slotShowcase.simpleChild2',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Two\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseSimple',\n id: 'org.openedx.frontend.widget.slotShowcase.simpleChild3',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Three\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseSimpleWithDefaultContent',\n id: 'org.openedx.frontend.widget.slotShowcase.simpleChild4',\n op: WidgetOperationTypes.APPEND,\n component: TakesProps\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseSimpleWithDefaultContent',\n id: 'org.openedx.frontend.widget.slotShowcase.simpleChild5',\n op: WidgetOperationTypes.APPEND,\n component: TakesPropsViaContext\n },\n\n // Custom Layout\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseCustom',\n id: 'org.openedx.frontend.widget.slotShowcase.customChild1',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget One\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseCustom',\n id: 'org.openedx.frontend.widget.slotShowcase.customChild2',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Two\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseCustom',\n id: 'org.openedx.frontend.widget.slotShowcase.customChild3',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Three\" />)\n },\n\n // Override custom layout\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseCustomConfig',\n id: 'org.openedx.frontend.widget.slotShowcase.customConfigChild1',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget One\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseCustomConfig',\n id: 'org.openedx.frontend.widget.slotShowcase.customConfigChild2',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Two\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseCustomConfig',\n id: 'org.openedx.frontend.widget.slotShowcase.customConfigChild3',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Three\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseCustomConfig',\n op: LayoutOperationTypes.REPLACE,\n element: <HorizontalSlotLayout />,\n },\n\n // Layout Options\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseLayoutWithOptions',\n op: LayoutOperationTypes.OPTIONS,\n options: {\n title: 'Bar',\n }\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseLayoutWithOptions',\n id: 'org.openedx.frontend.widget.slotShowcase.layoutWithOptionsChild1',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget One\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseLayoutWithOptions',\n id: 'org.openedx.frontend.widget.slotShowcase.layoutWithOptionsChild2',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Two\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseLayoutWithOptions',\n id: 'org.openedx.frontend.widget.slotShowcase.layoutWithOptionsChild3',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Three\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseLayoutWithOptionsDefault',\n id: 'org.openedx.frontend.widget.slotShowcase.layoutWithOptionsDefaultChild1',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget One\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseLayoutWithOptionsDefault',\n id: 'org.openedx.frontend.widget.slotShowcase.layoutWithOptionsDefaultChild2',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Two\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseLayoutWithOptionsDefault',\n id: 'org.openedx.frontend.widget.slotShowcase.layoutWithOptionsDefaultChild3',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Three\" />)\n },\n\n // TODO: Override Layout\n\n // Prepending\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcasePrepending',\n id: 'org.openedx.frontend.widget.slotShowcase.prependingChild1',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget One\" op=\"WidgetOperationTypes.APPEND\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcasePrepending',\n id: 'org.openedx.frontend.widget.slotShowcase.prependingChild2',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Two\" op=\"WidgetOperationTypes.APPEND\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcasePrepending',\n id: 'org.openedx.frontend.widget.slotShowcase.prependingChild3',\n op: WidgetOperationTypes.PREPEND,\n element: (<Widget title=\"Widget Three\" op=\"WidgetOperationTypes.PREPEND\" />)\n },\n\n // Inserting\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseInserting',\n id: 'slot-showcase.inserting.child4',\n op: WidgetOperationTypes.INSERT_AFTER,\n relatedId: 'org.openedx.frontend.widget.slotShowcase.insertingChild2',\n element: (<Widget title=\"Widget Four\" op=\"WidgetOperationTypes.INSERT_AFTER\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseInserting',\n id: 'slot-showcase.inserting.child5',\n op: WidgetOperationTypes.INSERT_BEFORE,\n relatedId: 'org.openedx.frontend.widget.slotShowcase.insertingChild2',\n element: (<Widget title=\"Widget Five\" op=\"WidgetOperationTypes.INSERT_BEFORE\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseInserting',\n id: 'org.openedx.frontend.widget.slotShowcase.insertingChild1',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget One\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseInserting',\n id: 'org.openedx.frontend.widget.slotShowcase.insertingChild2',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Two\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseInserting',\n id: 'org.openedx.frontend.widget.slotShowcase.insertingChild3',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Three\" />)\n },\n\n // Replacing\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseReplacing',\n id: 'org.openedx.frontend.widget.slotShowcase.replacingChild1',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget One\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseReplacing',\n id: 'org.openedx.frontend.widget.slotShowcase.replacingChild2',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Two\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseReplacing',\n id: 'org.openedx.frontend.widget.slotShowcase.replacingChild3',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Three\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseReplacing',\n id: 'org.openedx.frontend.widget.slotShowcase.replacingChild4',\n op: WidgetOperationTypes.REPLACE,\n relatedId: 'org.openedx.frontend.widget.slotShowcase.replacingChild2',\n element: (<Widget title=\"Widget Four\" op=\"WidgetOperationTypes.REPLACE\" />)\n },\n\n // Hiding\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseRemoving',\n id: 'org.openedx.frontend.widget.slotShowcase.removingChild1',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget One\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseRemoving',\n id: 'org.openedx.frontend.widget.slotShowcase.removingChild2',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Two\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseRemoving',\n id: 'org.openedx.frontend.widget.slotShowcase.removingChild3',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Three\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseRemoving',\n op: WidgetOperationTypes.REMOVE,\n relatedId: 'org.openedx.frontend.widget.slotShowcase.removingChild2',\n },\n\n // Widget Options\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseWidgetOptions',\n id: 'org.openedx.frontend.widget.slotShowcase.widgetOptionsChild1',\n op: WidgetOperationTypes.APPEND,\n component: WidgetWithOptions,\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseWidgetOptions',\n id: 'org.openedx.frontend.widget.slotShowcase.widgetOptionsChild2',\n op: WidgetOperationTypes.APPEND,\n component: WidgetWithOptions,\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseWidgetOptions',\n relatedId: 'org.openedx.frontend.widget.slotShowcase.widgetOptionsChild2',\n op: WidgetOperationTypes.OPTIONS,\n options: {\n title: 'Bar',\n }\n },\n\n // Widget filtering by role\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseFilterByRole',\n id: 'org.openedx.frontend.widget.slotShowcase.filterChild1',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget One\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseFilterByRole',\n id: 'org.openedx.frontend.widget.slotShowcase.filterChild2',\n role: 'org.openedx.frontend.role.slotShowcase.highlighted',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Two (highlighted)\" className=\"showcase-widget-highlighted\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseFilterByRole',\n id: 'org.openedx.frontend.widget.slotShowcase.filterChild3',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Three\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseFilterByRole',\n id: 'org.openedx.frontend.widget.slotShowcase.filterChild4',\n role: 'org.openedx.frontend.role.slotShowcase.highlighted',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Four (highlighted)\" className=\"showcase-widget-highlighted\" />)\n },\n\n // Header\n {\n slotId: 'org.openedx.frontend.slot.header.primaryLinks.v1',\n relatedId: 'org.openedx.frontend.widget.slotShowcase.headerLink',\n op: WidgetOperationTypes.OPTIONS,\n options: {\n title: 'Courses (modified)',\n },\n condition: {\n active: ['org.openedx.frontend.role.slotShowcase'],\n }\n },\n {\n slotId: 'org.openedx.frontend.slot.header.primaryLinks.v1',\n id: 'org.openedx.frontend.widget.slotShowcase.headerLinkAfter3',\n op: WidgetOperationTypes.INSERT_AFTER,\n relatedId: 'org.openedx.frontend.widget.slotShowcase.headerLink3',\n element: (<LinkMenuItem label=\"Link After 3\" url=\"#\" variant=\"navLink\" />),\n condition: {\n active: ['org.openedx.frontend.role.slotShowcase'],\n }\n },\n {\n slotId: 'org.openedx.frontend.slot.header.primaryLinks.v1',\n id: 'org.openedx.frontend.widget.slotShowcase.headerPrimaryLinksDropdownPrepend',\n op: WidgetOperationTypes.PREPEND,\n element: (\n <NavDropdownMenuSlot id=\"org.openedx.frontend.slot.header.primaryLinksDropdown.v1\" label=\"Resources\" />\n ),\n condition: {\n active: ['org.openedx.frontend.role.slotShowcase']\n }\n },\n {\n slotId: 'org.openedx.frontend.slot.header.primaryLinksDropdown.v1',\n id: 'org.openedx.frontend.widget.slotShowcase.headerPrimaryLinksDropdownAppend',\n op: WidgetOperationTypes.APPEND,\n element: (\n <LinkMenuItem label=\"Resource 1\" url=\"#\" variant=\"dropdownItem\" />\n ),\n condition: {\n active: ['org.openedx.frontend.role.slotShowcase'],\n }\n },\n {\n slotId: 'org.openedx.frontend.slot.header.primaryLinks.v1',\n id: 'org.openedx.frontend.widget.slotShowcase.headerLink3',\n op: WidgetOperationTypes.APPEND,\n element: (<LinkMenuItem label=\"Link 3\" url=\"#\" variant=\"navLink\" />),\n condition: {\n active: ['org.openedx.frontend.role.slotShowcase'],\n }\n },\n {\n slotId: 'org.openedx.frontend.slot.header.primaryLinks.v1',\n id: 'org.openedx.frontend.widget.slotShowcase.headerLink4',\n op: WidgetOperationTypes.APPEND,\n element: (<LinkMenuItem label=\"Link 4\" url=\"#\" variant=\"navLink\" />),\n condition: {\n active: ['org.openedx.frontend.role.slotShowcase'],\n }\n },\n ]\n};\n\nexport default app;\n"]}
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../../../../shell/dev/slotShowcase/app.tsx"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,YAAY,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAE9F,OAAO,oBAAoB,MAAM,wBAAwB,CAAC;AAC1D,OAAO,gBAAgB,MAAM,oBAAoB,CAAC;AAClD,OAAO,iBAAiB,MAAM,qBAAqB,CAAC;AAEpD,SAAS,MAAM,CAAC,EAAgH;QAAhH,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,OAA0F,EAArF,KAAK,cAAhC,4BAAkC,CAAF;IAC9C,OAAO,CACL,6BAAK,SAAS,EAAE,mBAAmB,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,EAAE,EAAE,IAAM,KAAK,eAC5D,KAAK,EACL,EAAE,IAAI,CACL,2BAAO,GAAG,OAAE,yBAAO,EAAE,GAAQ,SAAQ,CACtC,KACG,CACP,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,EAAE,SAAS,EAAyB;IACtD,OAAO,CACL,eAAK,SAAS,EAAC,iBAAiB,yEAAyD,yBAAO,SAAS,GAAQ,IAAM,CACxH,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB;IAC3B,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,MAAM,SAAS,GAAG,OAAO,WAAW,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;IAC5F,OAAO,CACL,eAAK,SAAS,EAAC,iBAAiB,2EAA2D,yBAAO,SAAS,GAAQ,IAAM,CAC1H,CAAC;AACJ,CAAC;AAED,MAAM,GAAG,GAAQ;IACf,KAAK,EAAE,uCAAuC;IAC9C,MAAM,EAAE,CAAC;YACP,EAAE,EAAE,yCAAyC;YAC7C,IAAI,EAAE,QAAQ;YACd,SAAS,EAAE,gBAAgB;YAC3B,MAAM,EAAE;gBACN,KAAK,EAAE,CAAC,wCAAwC,CAAC;aAClD;SACF,CAAC;IACF,KAAK,EAAE;QACL,SAAS;QACT;YACE,MAAM,EAAE,kDAAkD;YAC1D,EAAE,EAAE,uDAAuD;YAC3D,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,YAAY,GAAG,CAAC;SACzC;QACD;YACE,MAAM,EAAE,kDAAkD;YAC1D,EAAE,EAAE,uDAAuD;YAC3D,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,YAAY,GAAG,CAAC;SACzC;QACD;YACE,MAAM,EAAE,kDAAkD;YAC1D,EAAE,EAAE,uDAAuD;YAC3D,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,cAAc,GAAG,CAAC;SAC3C;QACD;YACE,MAAM,EAAE,oEAAoE;YAC5E,EAAE,EAAE,uDAAuD;YAC3D,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,SAAS,EAAE,UAAU;SACtB;QACD;YACE,MAAM,EAAE,oEAAoE;YAC5E,EAAE,EAAE,uDAAuD;YAC3D,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,SAAS,EAAE,oBAAoB;SAChC;QAED,gBAAgB;QAChB;YACE,MAAM,EAAE,kDAAkD;YAC1D,EAAE,EAAE,uDAAuD;YAC3D,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,YAAY,GAAG,CAAC;SACzC;QACD;YACE,MAAM,EAAE,kDAAkD;YAC1D,EAAE,EAAE,uDAAuD;YAC3D,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,YAAY,GAAG,CAAC;SACzC;QACD;YACE,MAAM,EAAE,kDAAkD;YAC1D,EAAE,EAAE,uDAAuD;YAC3D,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,cAAc,GAAG,CAAC;SAC3C;QAED,yBAAyB;QACzB;YACE,MAAM,EAAE,wDAAwD;YAChE,EAAE,EAAE,6DAA6D;YACjE,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,YAAY,GAAG,CAAC;SACzC;QACD;YACE,MAAM,EAAE,wDAAwD;YAChE,EAAE,EAAE,6DAA6D;YACjE,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,YAAY,GAAG,CAAC;SACzC;QACD;YACE,MAAM,EAAE,wDAAwD;YAChE,EAAE,EAAE,6DAA6D;YACjE,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,cAAc,GAAG,CAAC;SAC3C;QACD;YACE,MAAM,EAAE,wDAAwD;YAChE,EAAE,EAAE,oBAAoB,CAAC,OAAO;YAChC,OAAO,EAAE,KAAC,oBAAoB,KAAG;SAClC;QAED,iBAAiB;QACjB;YACE,MAAM,EAAE,6DAA6D;YACrE,EAAE,EAAE,oBAAoB,CAAC,OAAO;YAChC,OAAO,EAAE;gBACP,KAAK,EAAE,KAAK;aACb;SACF;QACD;YACE,MAAM,EAAE,6DAA6D;YACrE,EAAE,EAAE,kEAAkE;YACtE,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,YAAY,GAAG,CAAC;SACzC;QACD;YACE,MAAM,EAAE,6DAA6D;YACrE,EAAE,EAAE,kEAAkE;YACtE,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,YAAY,GAAG,CAAC;SACzC;QACD;YACE,MAAM,EAAE,6DAA6D;YACrE,EAAE,EAAE,kEAAkE;YACtE,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,cAAc,GAAG,CAAC;SAC3C;QACD;YACE,MAAM,EAAE,oEAAoE;YAC5E,EAAE,EAAE,yEAAyE;YAC7E,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,YAAY,GAAG,CAAC;SACzC;QACD;YACE,MAAM,EAAE,oEAAoE;YAC5E,EAAE,EAAE,yEAAyE;YAC7E,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,YAAY,GAAG,CAAC;SACzC;QACD;YACE,MAAM,EAAE,oEAAoE;YAC5E,EAAE,EAAE,yEAAyE;YAC7E,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,cAAc,GAAG,CAAC;SAC3C;QAED,wBAAwB;QAExB,aAAa;QACb;YACE,MAAM,EAAE,sDAAsD;YAC9D,EAAE,EAAE,2DAA2D;YAC/D,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,YAAY,EAAC,EAAE,EAAC,6BAA6B,GAAG,CAAC;SAC1E;QACD;YACE,MAAM,EAAE,sDAAsD;YAC9D,EAAE,EAAE,2DAA2D;YAC/D,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,YAAY,EAAC,EAAE,EAAC,6BAA6B,GAAG,CAAC;SAC1E;QACD;YACE,MAAM,EAAE,sDAAsD;YAC9D,EAAE,EAAE,2DAA2D;YAC/D,EAAE,EAAE,oBAAoB,CAAC,OAAO;YAChC,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,cAAc,EAAC,EAAE,EAAC,8BAA8B,GAAG,CAAC;SAC7E;QAED,YAAY;QACZ;YACE,MAAM,EAAE,qDAAqD;YAC7D,EAAE,EAAE,gCAAgC;YACpC,EAAE,EAAE,oBAAoB,CAAC,YAAY;YACrC,SAAS,EAAE,0DAA0D;YACrE,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,aAAa,EAAC,EAAE,EAAC,mCAAmC,GAAG,CAAC;SACjF;QACD;YACE,MAAM,EAAE,qDAAqD;YAC7D,EAAE,EAAE,gCAAgC;YACpC,EAAE,EAAE,oBAAoB,CAAC,aAAa;YACtC,SAAS,EAAE,0DAA0D;YACrE,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,aAAa,EAAC,EAAE,EAAC,oCAAoC,GAAG,CAAC;SAClF;QACD;YACE,MAAM,EAAE,qDAAqD;YAC7D,EAAE,EAAE,0DAA0D;YAC9D,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,YAAY,GAAG,CAAC;SACzC;QACD;YACE,MAAM,EAAE,qDAAqD;YAC7D,EAAE,EAAE,0DAA0D;YAC9D,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,YAAY,GAAG,CAAC;SACzC;QACD;YACE,MAAM,EAAE,qDAAqD;YAC7D,EAAE,EAAE,0DAA0D;YAC9D,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,cAAc,GAAG,CAAC;SAC3C;QAED,YAAY;QACZ;YACE,MAAM,EAAE,qDAAqD;YAC7D,EAAE,EAAE,0DAA0D;YAC9D,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,YAAY,GAAG,CAAC;SACzC;QACD;YACE,MAAM,EAAE,qDAAqD;YAC7D,EAAE,EAAE,0DAA0D;YAC9D,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,YAAY,GAAG,CAAC;SACzC;QACD;YACE,MAAM,EAAE,qDAAqD;YAC7D,EAAE,EAAE,0DAA0D;YAC9D,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,cAAc,GAAG,CAAC;SAC3C;QACD;YACE,MAAM,EAAE,qDAAqD;YAC7D,EAAE,EAAE,0DAA0D;YAC9D,EAAE,EAAE,oBAAoB,CAAC,OAAO;YAChC,SAAS,EAAE,0DAA0D;YACrE,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,aAAa,EAAC,EAAE,EAAC,8BAA8B,GAAG,CAAC;SAC5E;QAED,SAAS;QACT;YACE,MAAM,EAAE,oDAAoD;YAC5D,EAAE,EAAE,yDAAyD;YAC7D,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,YAAY,GAAG,CAAC;SACzC;QACD;YACE,MAAM,EAAE,oDAAoD;YAC5D,EAAE,EAAE,yDAAyD;YAC7D,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,YAAY,GAAG,CAAC;SACzC;QACD;YACE,MAAM,EAAE,oDAAoD;YAC5D,EAAE,EAAE,yDAAyD;YAC7D,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,cAAc,GAAG,CAAC;SAC3C;QACD;YACE,MAAM,EAAE,oDAAoD;YAC5D,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,SAAS,EAAE,yDAAyD;SACrE;QAED,iBAAiB;QACjB;YACE,MAAM,EAAE,yDAAyD;YACjE,EAAE,EAAE,8DAA8D;YAClE,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,SAAS,EAAE,iBAAiB;SAC7B;QACD;YACE,MAAM,EAAE,yDAAyD;YACjE,EAAE,EAAE,8DAA8D;YAClE,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,SAAS,EAAE,iBAAiB;SAC7B;QACD;YACE,MAAM,EAAE,yDAAyD;YACjE,SAAS,EAAE,8DAA8D;YACzE,EAAE,EAAE,oBAAoB,CAAC,OAAO;YAChC,OAAO,EAAE;gBACP,KAAK,EAAE,KAAK;aACb;SACF;QAED,2BAA2B;QAC3B;YACE,MAAM,EAAE,wDAAwD;YAChE,EAAE,EAAE,uDAAuD;YAC3D,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,YAAY,GAAG,CAAC;SACzC;QACD;YACE,MAAM,EAAE,wDAAwD;YAChE,EAAE,EAAE,uDAAuD;YAC3D,IAAI,EAAE,oDAAoD;YAC1D,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,0BAA0B,EAAC,SAAS,EAAC,6BAA6B,GAAG,CAAC;SAC/F;QACD;YACE,MAAM,EAAE,wDAAwD;YAChE,EAAE,EAAE,uDAAuD;YAC3D,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,cAAc,GAAG,CAAC;SAC3C;QACD;YACE,MAAM,EAAE,wDAAwD;YAChE,EAAE,EAAE,uDAAuD;YAC3D,IAAI,EAAE,oDAAoD;YAC1D,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,MAAM,IAAC,KAAK,EAAC,2BAA2B,EAAC,SAAS,EAAC,6BAA6B,GAAG,CAAC;SAChG;QAED,SAAS;QACT;YACE,MAAM,EAAE,kDAAkD;YAC1D,SAAS,EAAE,qDAAqD;YAChE,EAAE,EAAE,oBAAoB,CAAC,OAAO;YAChC,OAAO,EAAE;gBACP,KAAK,EAAE,oBAAoB;aAC5B;YACD,SAAS,EAAE;gBACT,MAAM,EAAE,CAAC,wCAAwC,CAAC;aACnD;SACF;QACD;YACE,MAAM,EAAE,kDAAkD;YAC1D,EAAE,EAAE,2DAA2D;YAC/D,EAAE,EAAE,oBAAoB,CAAC,YAAY;YACrC,SAAS,EAAE,sDAAsD;YACjE,OAAO,EAAE,CAAC,KAAC,YAAY,IAAC,KAAK,EAAC,cAAc,EAAC,GAAG,EAAC,GAAG,EAAC,OAAO,EAAC,SAAS,GAAG,CAAC;YAC1E,SAAS,EAAE;gBACT,MAAM,EAAE,CAAC,wCAAwC,CAAC;aACnD;SACF;QACD;YACE,MAAM,EAAE,kDAAkD;YAC1D,EAAE,EAAE,4EAA4E;YAChF,EAAE,EAAE,oBAAoB,CAAC,OAAO;YAChC,OAAO,EAAE,CACP,KAAC,mBAAmB,IAAC,EAAE,EAAC,0DAA0D,EAAC,KAAK,EAAC,WAAW,GAAG,CACxG;YACD,SAAS,EAAE;gBACT,MAAM,EAAE,CAAC,wCAAwC,CAAC;aACnD;SACF;QACD;YACE,MAAM,EAAE,0DAA0D;YAClE,EAAE,EAAE,2EAA2E;YAC/E,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CACP,KAAC,YAAY,IAAC,KAAK,EAAC,YAAY,EAAC,GAAG,EAAC,GAAG,EAAC,OAAO,EAAC,cAAc,GAAG,CACnE;YACD,SAAS,EAAE;gBACT,MAAM,EAAE,CAAC,wCAAwC,CAAC;aACnD;SACF;QACD;YACE,MAAM,EAAE,kDAAkD;YAC1D,EAAE,EAAE,sDAAsD;YAC1D,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,YAAY,IAAC,KAAK,EAAC,QAAQ,EAAC,GAAG,EAAC,GAAG,EAAC,OAAO,EAAC,SAAS,GAAG,CAAC;YACpE,SAAS,EAAE;gBACT,MAAM,EAAE,CAAC,wCAAwC,CAAC;aACnD;SACF;QACD;YACE,MAAM,EAAE,kDAAkD;YAC1D,EAAE,EAAE,sDAAsD;YAC1D,EAAE,EAAE,oBAAoB,CAAC,MAAM;YAC/B,OAAO,EAAE,CAAC,KAAC,YAAY,IAAC,KAAK,EAAC,QAAQ,EAAC,GAAG,EAAC,GAAG,EAAC,OAAO,EAAC,SAAS,GAAG,CAAC;YACpE,SAAS,EAAE;gBACT,MAAM,EAAE,CAAC,wCAAwC,CAAC;aACnD;SACF;KACF;CACF,CAAC;AAEF,eAAe,GAAG,CAAC","sourcesContent":["import { NavDropdownMenuSlot } from '../..';\nimport LinkMenuItem from '../../menus/LinkMenuItem';\nimport { LayoutOperationTypes, WidgetOperationTypes, useSlotContext } from '../../../runtime';\nimport { App } from '../../../types';\nimport HorizontalSlotLayout from './HorizontalSlotLayout';\nimport SlotShowcasePage from './SlotShowcasePage';\nimport WidgetWithOptions from './WidgetWithOptions';\n\nfunction Widget({ title, op, className, ...props }: { title: string; op?: string; className?: string } & Record<string, unknown>) {\n return (\n <div className={`showcase-widget ${className ?? ''}`} {...props}>\n {title}\n {op && (\n <span>{' '}(<code>{op}</code>)</span>\n )}\n </div>\n );\n}\n\nfunction TakesProps({ aSlotProp }: { aSlotProp: string }) {\n return (\n <div className=\"showcase-widget\">And this is a slot prop that was passed down via props: <code>{aSlotProp}</code></div>\n );\n}\n\nfunction TakesPropsViaContext() {\n const slotContext = useSlotContext();\n const aSlotProp = typeof slotContext.aSlotProp === 'string' ? slotContext.aSlotProp : 'foo';\n return (\n <div className=\"showcase-widget\">And this is the same prop, but accessed via slot context: <code>{aSlotProp}</code></div>\n );\n}\n\nconst app: App = {\n appId: 'org.openedx.frontend.app.slotShowcase',\n routes: [{\n id: 'org.openedx.frontend.route.slotShowcase',\n path: '/slots',\n Component: SlotShowcasePage,\n handle: {\n roles: ['org.openedx.frontend.role.slotShowcase'],\n }\n }],\n slots: [\n // Simple\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseSimple',\n id: 'org.openedx.frontend.widget.slotShowcase.simpleChild1',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget One\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseSimple',\n id: 'org.openedx.frontend.widget.slotShowcase.simpleChild2',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Two\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseSimple',\n id: 'org.openedx.frontend.widget.slotShowcase.simpleChild3',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Three\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseSimpleWithDefaultContent',\n id: 'org.openedx.frontend.widget.slotShowcase.simpleChild4',\n op: WidgetOperationTypes.APPEND,\n component: TakesProps\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseSimpleWithDefaultContent',\n id: 'org.openedx.frontend.widget.slotShowcase.simpleChild5',\n op: WidgetOperationTypes.APPEND,\n component: TakesPropsViaContext\n },\n\n // Custom Layout\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseCustom',\n id: 'org.openedx.frontend.widget.slotShowcase.customChild1',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget One\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseCustom',\n id: 'org.openedx.frontend.widget.slotShowcase.customChild2',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Two\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseCustom',\n id: 'org.openedx.frontend.widget.slotShowcase.customChild3',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Three\" />)\n },\n\n // Override custom layout\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseCustomConfig',\n id: 'org.openedx.frontend.widget.slotShowcase.customConfigChild1',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget One\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseCustomConfig',\n id: 'org.openedx.frontend.widget.slotShowcase.customConfigChild2',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Two\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseCustomConfig',\n id: 'org.openedx.frontend.widget.slotShowcase.customConfigChild3',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Three\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseCustomConfig',\n op: LayoutOperationTypes.REPLACE,\n element: <HorizontalSlotLayout />,\n },\n\n // Layout Options\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseLayoutWithOptions',\n op: LayoutOperationTypes.OPTIONS,\n options: {\n title: 'Bar',\n }\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseLayoutWithOptions',\n id: 'org.openedx.frontend.widget.slotShowcase.layoutWithOptionsChild1',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget One\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseLayoutWithOptions',\n id: 'org.openedx.frontend.widget.slotShowcase.layoutWithOptionsChild2',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Two\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseLayoutWithOptions',\n id: 'org.openedx.frontend.widget.slotShowcase.layoutWithOptionsChild3',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Three\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseLayoutWithOptionsDefault',\n id: 'org.openedx.frontend.widget.slotShowcase.layoutWithOptionsDefaultChild1',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget One\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseLayoutWithOptionsDefault',\n id: 'org.openedx.frontend.widget.slotShowcase.layoutWithOptionsDefaultChild2',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Two\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseLayoutWithOptionsDefault',\n id: 'org.openedx.frontend.widget.slotShowcase.layoutWithOptionsDefaultChild3',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Three\" />)\n },\n\n // TODO: Override Layout\n\n // Prepending\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcasePrepending',\n id: 'org.openedx.frontend.widget.slotShowcase.prependingChild1',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget One\" op=\"WidgetOperationTypes.APPEND\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcasePrepending',\n id: 'org.openedx.frontend.widget.slotShowcase.prependingChild2',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Two\" op=\"WidgetOperationTypes.APPEND\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcasePrepending',\n id: 'org.openedx.frontend.widget.slotShowcase.prependingChild3',\n op: WidgetOperationTypes.PREPEND,\n element: (<Widget title=\"Widget Three\" op=\"WidgetOperationTypes.PREPEND\" />)\n },\n\n // Inserting\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseInserting',\n id: 'slot-showcase.inserting.child4',\n op: WidgetOperationTypes.INSERT_AFTER,\n relatedId: 'org.openedx.frontend.widget.slotShowcase.insertingChild2',\n element: (<Widget title=\"Widget Four\" op=\"WidgetOperationTypes.INSERT_AFTER\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseInserting',\n id: 'slot-showcase.inserting.child5',\n op: WidgetOperationTypes.INSERT_BEFORE,\n relatedId: 'org.openedx.frontend.widget.slotShowcase.insertingChild2',\n element: (<Widget title=\"Widget Five\" op=\"WidgetOperationTypes.INSERT_BEFORE\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseInserting',\n id: 'org.openedx.frontend.widget.slotShowcase.insertingChild1',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget One\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseInserting',\n id: 'org.openedx.frontend.widget.slotShowcase.insertingChild2',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Two\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseInserting',\n id: 'org.openedx.frontend.widget.slotShowcase.insertingChild3',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Three\" />)\n },\n\n // Replacing\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseReplacing',\n id: 'org.openedx.frontend.widget.slotShowcase.replacingChild1',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget One\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseReplacing',\n id: 'org.openedx.frontend.widget.slotShowcase.replacingChild2',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Two\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseReplacing',\n id: 'org.openedx.frontend.widget.slotShowcase.replacingChild3',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Three\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseReplacing',\n id: 'org.openedx.frontend.widget.slotShowcase.replacingChild4',\n op: WidgetOperationTypes.REPLACE,\n relatedId: 'org.openedx.frontend.widget.slotShowcase.replacingChild2',\n element: (<Widget title=\"Widget Four\" op=\"WidgetOperationTypes.REPLACE\" />)\n },\n\n // Hiding\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseRemoving',\n id: 'org.openedx.frontend.widget.slotShowcase.removingChild1',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget One\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseRemoving',\n id: 'org.openedx.frontend.widget.slotShowcase.removingChild2',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Two\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseRemoving',\n id: 'org.openedx.frontend.widget.slotShowcase.removingChild3',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Three\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseRemoving',\n op: WidgetOperationTypes.REMOVE,\n relatedId: 'org.openedx.frontend.widget.slotShowcase.removingChild2',\n },\n\n // Widget Options\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseWidgetOptions',\n id: 'org.openedx.frontend.widget.slotShowcase.widgetOptionsChild1',\n op: WidgetOperationTypes.APPEND,\n component: WidgetWithOptions,\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseWidgetOptions',\n id: 'org.openedx.frontend.widget.slotShowcase.widgetOptionsChild2',\n op: WidgetOperationTypes.APPEND,\n component: WidgetWithOptions,\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseWidgetOptions',\n relatedId: 'org.openedx.frontend.widget.slotShowcase.widgetOptionsChild2',\n op: WidgetOperationTypes.OPTIONS,\n options: {\n title: 'Bar',\n }\n },\n\n // Widget filtering by role\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseFilterByRole',\n id: 'org.openedx.frontend.widget.slotShowcase.filterChild1',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget One\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseFilterByRole',\n id: 'org.openedx.frontend.widget.slotShowcase.filterChild2',\n role: 'org.openedx.frontend.role.slotShowcase.highlighted',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Two (highlighted)\" className=\"showcase-widget-highlighted\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseFilterByRole',\n id: 'org.openedx.frontend.widget.slotShowcase.filterChild3',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Three\" />)\n },\n {\n slotId: 'org.openedx.frontend.slot.dev.slotShowcaseFilterByRole',\n id: 'org.openedx.frontend.widget.slotShowcase.filterChild4',\n role: 'org.openedx.frontend.role.slotShowcase.highlighted',\n op: WidgetOperationTypes.APPEND,\n element: (<Widget title=\"Widget Four (highlighted)\" className=\"showcase-widget-highlighted\" />)\n },\n\n // Header\n {\n slotId: 'org.openedx.frontend.slot.header.primaryLinks.v1',\n relatedId: 'org.openedx.frontend.widget.slotShowcase.headerLink',\n op: WidgetOperationTypes.OPTIONS,\n options: {\n title: 'Courses (modified)',\n },\n condition: {\n active: ['org.openedx.frontend.role.slotShowcase'],\n }\n },\n {\n slotId: 'org.openedx.frontend.slot.header.primaryLinks.v1',\n id: 'org.openedx.frontend.widget.slotShowcase.headerLinkAfter3',\n op: WidgetOperationTypes.INSERT_AFTER,\n relatedId: 'org.openedx.frontend.widget.slotShowcase.headerLink3',\n element: (<LinkMenuItem label=\"Link After 3\" url=\"#\" variant=\"navLink\" />),\n condition: {\n active: ['org.openedx.frontend.role.slotShowcase'],\n }\n },\n {\n slotId: 'org.openedx.frontend.slot.header.primaryLinks.v1',\n id: 'org.openedx.frontend.widget.slotShowcase.headerPrimaryLinksDropdownPrepend',\n op: WidgetOperationTypes.PREPEND,\n element: (\n <NavDropdownMenuSlot id=\"org.openedx.frontend.slot.header.primaryLinksDropdown.v1\" label=\"Resources\" />\n ),\n condition: {\n active: ['org.openedx.frontend.role.slotShowcase']\n }\n },\n {\n slotId: 'org.openedx.frontend.slot.header.primaryLinksDropdown.v1',\n id: 'org.openedx.frontend.widget.slotShowcase.headerPrimaryLinksDropdownAppend',\n op: WidgetOperationTypes.APPEND,\n element: (\n <LinkMenuItem label=\"Resource 1\" url=\"#\" variant=\"dropdownItem\" />\n ),\n condition: {\n active: ['org.openedx.frontend.role.slotShowcase'],\n }\n },\n {\n slotId: 'org.openedx.frontend.slot.header.primaryLinks.v1',\n id: 'org.openedx.frontend.widget.slotShowcase.headerLink3',\n op: WidgetOperationTypes.APPEND,\n element: (<LinkMenuItem label=\"Link 3\" url=\"#\" variant=\"navLink\" />),\n condition: {\n active: ['org.openedx.frontend.role.slotShowcase'],\n }\n },\n {\n slotId: 'org.openedx.frontend.slot.header.primaryLinks.v1',\n id: 'org.openedx.frontend.widget.slotShowcase.headerLink4',\n op: WidgetOperationTypes.APPEND,\n element: (<LinkMenuItem label=\"Link 4\" url=\"#\" variant=\"navLink\" />),\n condition: {\n active: ['org.openedx.frontend.role.slotShowcase'],\n }\n },\n ]\n};\n\nexport default app;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"CopyrightNotice.js","sourceRoot":"","sources":["../../../shell/footer/CopyrightNotice.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAW9C,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EAAE,KAAK,EAAE,WAAW,EAAwB;IAClF,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAE/B,sDAAsD;IACtD,MAAM,UAAU,GAAG,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,MAAM,CAAC,QAAQ,CAAC;IAE5C,OAAO,CACL,eAAK,SAAS,EAAC,qBAAqB,aAClC,2CAAmB,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,cAAc,EACxD,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,CAC3B,KAAC,SAAS,IACR,WAAW,EAAE,WAAW,EACxB,MAAM,EAAC,QAAQ,YAEd,UAAU,GACD,CACb,CAAC,CAAC,CAAC,CACF,yBAAO,UAAU,GAAQ,CAC1B,EACD,+BAAc,IACV,CACP,CAAC;AACJ,CAAC","sourcesContent":["import { Hyperlink } from '@openedx/paragon';\n\nimport { useSiteConfig } from '../../runtime';\n\ninterface CopyrightNoticeProps {\n title?: string,\n /**\n * The URL that the copyright notice should link to when a user clicks on the title. If not set,\n * the title will not be a link.\n */\n destination?: string,\n}\n\nexport default function CopyrightNotice({ title, destination }: CopyrightNoticeProps) {\n const config = useSiteConfig();\n\n // Allow overrides via props and fallback to defaults.\n const finalTitle = title ?? config.siteName;\n\n return (\n <div className=\"text-center x-small\">\n <span>&copy;&nbsp;{new Date().getFullYear()}&nbsp;</span>\n {destination !== undefined ? (\n <Hyperlink\n destination={destination}\n target=\"_blank\"\n >\n {finalTitle}\n </Hyperlink>\n ) : (\n <span>{finalTitle}</span>\n )}\n <span>.</span>\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"CopyrightNotice.js","sourceRoot":"","sources":["../../../shell/footer/CopyrightNotice.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAW9C,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EAAE,KAAK,EAAE,WAAW,EAAwB;IAClF,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAE/B,sDAAsD;IACtD,MAAM,UAAU,GAAG,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,MAAM,CAAC,QAAQ,CAAC;IAE5C,OAAO,CACL,eAAK,SAAS,EAAC,qBAAqB,aAClC,2CAAmB,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,cAAc,EACxD,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,CAC3B,KAAC,SAAS,IACR,WAAW,EAAE,WAAW,EACxB,MAAM,EAAC,QAAQ,YAEd,UAAU,GACD,CACb,CAAC,CAAC,CAAC,CACF,yBAAO,UAAU,GAAQ,CAC1B,EACD,+BAAc,IACV,CACP,CAAC;AACJ,CAAC","sourcesContent":["import { Hyperlink } from '@openedx/paragon';\n\nimport { useSiteConfig } from '../../runtime';\n\ninterface CopyrightNoticeProps {\n title?: string;\n /**\n * The URL that the copyright notice should link to when a user clicks on the title. If not set,\n * the title will not be a link.\n */\n destination?: string;\n}\n\nexport default function CopyrightNotice({ title, destination }: CopyrightNoticeProps) {\n const config = useSiteConfig();\n\n // Allow overrides via props and fallback to defaults.\n const finalTitle = title ?? config.siteName;\n\n return (\n <div className=\"text-center x-small\">\n <span>&copy;&nbsp;{new Date().getFullYear()}&nbsp;</span>\n {destination !== undefined ? (\n <Hyperlink\n destination={destination}\n target=\"_blank\"\n >\n {finalTitle}\n </Hyperlink>\n ) : (\n <span>{finalTitle}</span>\n )}\n <span>.</span>\n </div>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"LanguageMenuItem.js","sourceRoot":"","sources":["../../../shell/footer/LanguageMenuItem.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAEpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAShD,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAE,QAAQ,EAAyB;IAC1E,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE;QACnC,kBAAkB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IAEpB,OAAO,CACL,KAAC,QAAQ,CAAC,IAAI,IAAqB,OAAO,EAAE,WAAW,YACpD,QAAQ,CAAC,IAAI,IADI,QAAQ,CAAC,IAAI,CAEjB,CACjB,CAAC;AACJ,CAAC","sourcesContent":["import { Dropdown } from '@openedx/paragon';\nimport { useCallback } from 'react';\n\nimport { updateSiteLanguage } from './data/api';\n\ninterface LanguageMenuItemProps {\n language: {\n code: string,\n name: string,\n },\n}\n\nexport default function LanguageMenuItem({ language }: LanguageMenuItemProps) {\n const handleClick = useCallback(() => {\n updateSiteLanguage(language.code);\n }, [language.code]);\n\n return (\n <Dropdown.Item key={language.code} onClick={handleClick}>\n {language.name}\n </Dropdown.Item>\n );\n}\n"]}
1
+ {"version":3,"file":"LanguageMenuItem.js","sourceRoot":"","sources":["../../../shell/footer/LanguageMenuItem.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAEpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAShD,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAE,QAAQ,EAAyB;IAC1E,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE;QACnC,kBAAkB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IAEpB,OAAO,CACL,KAAC,QAAQ,CAAC,IAAI,IAAqB,OAAO,EAAE,WAAW,YACpD,QAAQ,CAAC,IAAI,IADI,QAAQ,CAAC,IAAI,CAEjB,CACjB,CAAC;AACJ,CAAC","sourcesContent":["import { Dropdown } from '@openedx/paragon';\nimport { useCallback } from 'react';\n\nimport { updateSiteLanguage } from './data/api';\n\ninterface LanguageMenuItemProps {\n language: {\n code: string;\n name: string;\n };\n}\n\nexport default function LanguageMenuItem({ language }: LanguageMenuItemProps) {\n const handleClick = useCallback(() => {\n updateSiteLanguage(language.code);\n }, [language.code]);\n\n return (\n <Dropdown.Item key={language.code} onClick={handleClick}>\n {language.name}\n </Dropdown.Item>\n );\n}\n"]}
@@ -1 +1 @@
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"]}
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"]}
@@ -1 +1 @@
1
- {"version":3,"file":"HelpButton.js","sourceRoot":"","sources":["../../../shell/header/HelpButton.tsx"],"names":[],"mappings":";AAAA,OAAO,YAAY,MAAM,uBAAuB,CAAC;AACjD,OAAO,QAAQ,MAAM,mBAAmB,CAAC;AAMzC,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EAAE,MAAM,EAAmB;IAC5D,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;IACrB,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,OAAO,CACL,KAAC,YAAY,IACX,KAAK,EAAE,QAAQ,CAAC,aAAa,CAAC,EAC9B,GAAG,EAAE,GAAG,EACR,OAAO,EAAC,SAAS,GACjB,CACH,CAAC;AACJ,CAAC","sourcesContent":["import LinkMenuItem from '../menus/LinkMenuItem';\nimport messages from '../Shell.messages';\n\ninterface HelpButtonProps {\n getUrl: () => string | undefined,\n}\n\nexport default function HelpButton({ getUrl }: HelpButtonProps) {\n const url = getUrl();\n if (!url) return null;\n return (\n <LinkMenuItem\n label={messages['header.help']}\n url={url}\n variant=\"navLink\"\n />\n );\n}\n"]}
1
+ {"version":3,"file":"HelpButton.js","sourceRoot":"","sources":["../../../shell/header/HelpButton.tsx"],"names":[],"mappings":";AAAA,OAAO,YAAY,MAAM,uBAAuB,CAAC;AACjD,OAAO,QAAQ,MAAM,mBAAmB,CAAC;AAMzC,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EAAE,MAAM,EAAmB;IAC5D,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;IACrB,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,OAAO,CACL,KAAC,YAAY,IACX,KAAK,EAAE,QAAQ,CAAC,aAAa,CAAC,EAC9B,GAAG,EAAE,GAAG,EACR,OAAO,EAAC,SAAS,GACjB,CACH,CAAC;AACJ,CAAC","sourcesContent":["import LinkMenuItem from '../menus/LinkMenuItem';\nimport messages from '../Shell.messages';\n\ninterface HelpButtonProps {\n getUrl: () => string | undefined;\n}\n\nexport default function HelpButton({ getUrl }: HelpButtonProps) {\n const url = getUrl();\n if (!url) return null;\n return (\n <LinkMenuItem\n label={messages['header.help']}\n url={url}\n variant=\"navLink\"\n />\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"AnonymousMenu.js","sourceRoot":"","sources":["../../../../shell/header/anonymous-menu/AnonymousMenu.tsx"],"names":[],"mappings":";AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAMxC,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EAAE,SAAS,EAAsB;IACrE,OAAO,CACL,cAAK,SAAS,EAAE,UAAU,CAAC,2DAA2D,EAAE,SAAS,CAAC,YAChG,KAAC,IAAI,IAAC,EAAE,EAAC,mDAAmD,GAAG,GAC3D,CACP,CAAC;AACJ,CAAC","sourcesContent":["import classNames from 'classnames';\nimport { Slot } from '../../../runtime';\n\ninterface AnonymousMenuProps {\n className?: string,\n}\n\nexport default function AnonymousMenu({ className }: AnonymousMenuProps) {\n return (\n <div className={classNames('d-flex flex-nowrap align-items-center flex-shrink-0 gap-3', className)}>\n <Slot id=\"org.openedx.frontend.slot.header.anonymousMenu.v1\" />\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"AnonymousMenu.js","sourceRoot":"","sources":["../../../../shell/header/anonymous-menu/AnonymousMenu.tsx"],"names":[],"mappings":";AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAMxC,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EAAE,SAAS,EAAsB;IACrE,OAAO,CACL,cAAK,SAAS,EAAE,UAAU,CAAC,2DAA2D,EAAE,SAAS,CAAC,YAChG,KAAC,IAAI,IAAC,EAAE,EAAC,mDAAmD,GAAG,GAC3D,CACP,CAAC;AACJ,CAAC","sourcesContent":["import classNames from 'classnames';\nimport { Slot } from '../../../runtime';\n\ninterface AnonymousMenuProps {\n className?: string;\n}\n\nexport default function AnonymousMenu({ className }: AnonymousMenuProps) {\n return (\n <div className={classNames('d-flex flex-nowrap align-items-center flex-shrink-0 gap-3', className)}>\n <Slot id=\"org.openedx.frontend.slot.header.anonymousMenu.v1\" />\n </div>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","sourceRoot":"","sources":["../../../../../shell/header/course-bar/data/service.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAuBjG,SAAS,iCAAiC,CAAC,QAAqC;IAC9E,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IACvC,OAAO;QACL,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAc,EAAE,EAAE,CAAC,CAAC;YAC/C,KAAK,EAAE,GAAG,CAAC,KAAK,KAAK,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK;YACzD,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,GAAG,EAAE,GAAG,CAAC,GAAG;SACb,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED,MAAM,UAAgB,2BAA2B,CAAC,QAAgB;;QAChE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,GAAG,CAAC,GAAG,aAAa,EAAE,CAAC,UAAU,oCAAoC,QAAQ,EAAE,CAAC,CAAC;QAErI,OAAO,iCAAiC,CAAC,IAAI,CAAC,CAAC;IACjD,CAAC;CAAA;AAED,MAAM,UAAU,gCAAgC,CAAC,QAAgB;IAC/D,OAAO,CAAC,4CAA4C,EAAE,QAAQ,CAAC,CAAC;AAClE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,IAAiB,EAAE,QAAgB;;IAC/D,IAAI,IAAI,GAA8C,IAAI,CAAC;IAC3D,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;QAC9C,MAAM,KAAK,GAAG,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,WAAW,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC5E,IAAI,KAAK,IAAI,CAAC,CAAC,IAAI,IAAI,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACzD,IAAI,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC;QAC7C,CAAC;IACH,CAAC;IACD,OAAO,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,GAAG,mCAAI,IAAI,CAAC;AAC3B,CAAC","sourcesContent":["import { matchPath } from 'react-router-dom';\nimport { getSiteConfig, getAuthenticatedHttpClient, camelCaseObject } from '../../../../runtime';\n\n// Raw API response from /api/course_home/course_metadata/\ninterface RawCourseTab {\n tab_id: string,\n title: string,\n url: string,\n}\n\ninterface RawCourseHomeCourseMetadata {\n tabs: RawCourseTab[],\n}\n\nexport interface CourseTab {\n tabId: string,\n title: string,\n url: string,\n}\n\nexport interface CourseHomeCourseMetadata {\n tabs: CourseTab[],\n}\n\nfunction normalizeCourseHomeCourseMetadata(metadata: RawCourseHomeCourseMetadata): CourseHomeCourseMetadata {\n const data = camelCaseObject(metadata);\n return {\n tabs: (data.tabs || []).map((tab: CourseTab) => ({\n tabId: tab.tabId === 'courseware' ? 'outline' : tab.tabId,\n title: tab.title,\n url: tab.url,\n })),\n };\n}\n\nexport async function getCourseHomeCourseMetadata(courseId: string): Promise<CourseHomeCourseMetadata> {\n const { data } = await getAuthenticatedHttpClient().get(`${getSiteConfig().lmsBaseUrl}/api/course_home/course_metadata/${courseId}`);\n\n return normalizeCourseHomeCourseMetadata(data);\n}\n\nexport function courseHomeCourseMetadataQueryKey(courseId: string): [string, string] {\n return ['org.openedx.frontend.app.header.courseMeta', courseId];\n}\n\n/*\n * Returns the tab whose URL pathname is the longest prefix match against\n * `pathname`, or null if none match. Used by the navigation bar to mark the\n * active tab and by the masquerade redirect to decide whether the demoted\n * user can still see the page they're on.\n */\nexport function findActiveTab(tabs: CourseTab[], pathname: string): CourseTab | null {\n let best: { tab: CourseTab, length: number } | null = null;\n for (const tab of tabs) {\n const tabPathname = new URL(tab.url).pathname;\n const match = matchPath({ path: `${tabPathname}/*`, end: false }, pathname);\n if (match && (!best || tabPathname.length > best.length)) {\n best = { tab, length: tabPathname.length };\n }\n }\n return best?.tab ?? null;\n}\n"]}
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../../../../shell/header/course-bar/data/service.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAuBjG,SAAS,iCAAiC,CAAC,QAAqC;IAC9E,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IACvC,OAAO;QACL,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAc,EAAE,EAAE,CAAC,CAAC;YAC/C,KAAK,EAAE,GAAG,CAAC,KAAK,KAAK,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK;YACzD,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,GAAG,EAAE,GAAG,CAAC,GAAG;SACb,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED,MAAM,UAAgB,2BAA2B,CAAC,QAAgB;;QAChE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,GAAG,CAAC,GAAG,aAAa,EAAE,CAAC,UAAU,oCAAoC,QAAQ,EAAE,CAAC,CAAC;QAErI,OAAO,iCAAiC,CAAC,IAAI,CAAC,CAAC;IACjD,CAAC;CAAA;AAED,MAAM,UAAU,gCAAgC,CAAC,QAAgB;IAC/D,OAAO,CAAC,4CAA4C,EAAE,QAAQ,CAAC,CAAC;AAClE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,IAAiB,EAAE,QAAgB;;IAC/D,IAAI,IAAI,GAA8C,IAAI,CAAC;IAC3D,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;QAC9C,MAAM,KAAK,GAAG,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,WAAW,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC5E,IAAI,KAAK,IAAI,CAAC,CAAC,IAAI,IAAI,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACzD,IAAI,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC;QAC7C,CAAC;IACH,CAAC;IACD,OAAO,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,GAAG,mCAAI,IAAI,CAAC;AAC3B,CAAC","sourcesContent":["import { matchPath } from 'react-router-dom';\nimport { getSiteConfig, getAuthenticatedHttpClient, camelCaseObject } from '../../../../runtime';\n\n// Raw API response from /api/course_home/course_metadata/\ninterface RawCourseTab {\n tab_id: string;\n title: string;\n url: string;\n}\n\ninterface RawCourseHomeCourseMetadata {\n tabs: RawCourseTab[];\n}\n\nexport interface CourseTab {\n tabId: string;\n title: string;\n url: string;\n}\n\nexport interface CourseHomeCourseMetadata {\n tabs: CourseTab[];\n}\n\nfunction normalizeCourseHomeCourseMetadata(metadata: RawCourseHomeCourseMetadata): CourseHomeCourseMetadata {\n const data = camelCaseObject(metadata);\n return {\n tabs: (data.tabs || []).map((tab: CourseTab) => ({\n tabId: tab.tabId === 'courseware' ? 'outline' : tab.tabId,\n title: tab.title,\n url: tab.url,\n })),\n };\n}\n\nexport async function getCourseHomeCourseMetadata(courseId: string): Promise<CourseHomeCourseMetadata> {\n const { data } = await getAuthenticatedHttpClient().get(`${getSiteConfig().lmsBaseUrl}/api/course_home/course_metadata/${courseId}`);\n\n return normalizeCourseHomeCourseMetadata(data);\n}\n\nexport function courseHomeCourseMetadataQueryKey(courseId: string): [string, string] {\n return ['org.openedx.frontend.app.header.courseMeta', courseId];\n}\n\n/*\n * Returns the tab whose URL pathname is the longest prefix match against\n * `pathname`, or null if none match. Used by the navigation bar to mark the\n * active tab and by the masquerade redirect to decide whether the demoted\n * user can still see the page they're on.\n */\nexport function findActiveTab(tabs: CourseTab[], pathname: string): CourseTab | null {\n let best: { tab: CourseTab; length: number } | null = null;\n for (const tab of tabs) {\n const tabPathname = new URL(tab.url).pathname;\n const match = matchPath({ path: `${tabPathname}/*`, end: false }, pathname);\n if (match && (!best || tabPathname.length > best.length)) {\n best = { tab, length: tabPathname.length };\n }\n }\n return best?.tab ?? null;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"StudioLink.js","sourceRoot":"","sources":["../../../../../shell/header/course-bar/masquerade/StudioLink.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClF,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,OAAO,QAAQ,MAAM,YAAY,CAAC;AAOlC,SAAS,cAAc,CAAC,QAAiB,EAAE,MAAe;IACxD,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC,UAAU,CAAC;IACxC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,GAAG,IAAI,cAAc,MAAM,EAAE,CAAC;IACvC,CAAC;IACD,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,GAAG,IAAI,WAAW,QAAQ,EAAE,CAAC;IACtC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAS;IACpD,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,GAAG,GAAG,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAE7C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CACL,8BACE,aAAI,SAAS,EAAC,cAAc,GAAG,EAC/B,eAAM,SAAS,EAAC,0BAA0B,YACxC,KAAC,gBAAgB,oBAAK,QAAQ,CAAC,iBAAiB,EAAI,GAC/C,EACP,eAAM,SAAS,EAAC,WAAW,YACzB,KAAC,MAAM,IAAC,OAAO,EAAC,yBAAyB,EAAC,IAAI,EAAE,GAAG,YAChD,aAAa,CAAC,QAAQ,CAAC,WAAW,CAAC,GAC7B,GACJ,IACN,CACJ,CAAC;AACJ,CAAC;AAED,eAAe,UAAU,CAAC","sourcesContent":["import { useIntl, FormattedMessage, getSiteConfig } from '@openedx/frontend-base';\nimport { Button } from '@openedx/paragon';\n\nimport messages from './messages';\n\ninterface Props {\n courseId?: string,\n unitId?: string,\n}\n\nfunction buildStudioUrl(courseId?: string, unitId?: string): string | null {\n const base = getSiteConfig().cmsBaseUrl;\n if (!base) {\n return null;\n }\n if (unitId) {\n return `${base}/container/${unitId}`;\n }\n if (courseId) {\n return `${base}/course/${courseId}`;\n }\n return null;\n}\n\nexport function StudioLink({ courseId, unitId }: Props) {\n const { formatMessage } = useIntl();\n const url = buildStudioUrl(courseId, unitId);\n\n if (!url) {\n return null;\n }\n\n return (\n <>\n <hr className=\"border-light\" />\n <span className=\"mr-2 mt-1 col-form-label\">\n <FormattedMessage {...messages.titleViewCourseIn} />\n </span>\n <span className=\"mx-1 my-1\">\n <Button variant=\"inverse-outline-primary\" href={url}>\n {formatMessage(messages.titleStudio)}\n </Button>\n </span>\n </>\n );\n}\n\nexport default StudioLink;\n"]}
1
+ {"version":3,"file":"StudioLink.js","sourceRoot":"","sources":["../../../../../shell/header/course-bar/masquerade/StudioLink.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClF,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,OAAO,QAAQ,MAAM,YAAY,CAAC;AAOlC,SAAS,cAAc,CAAC,QAAiB,EAAE,MAAe;IACxD,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC,UAAU,CAAC;IACxC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,GAAG,IAAI,cAAc,MAAM,EAAE,CAAC;IACvC,CAAC;IACD,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,GAAG,IAAI,WAAW,QAAQ,EAAE,CAAC;IACtC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAS;IACpD,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,CAAC;IACpC,MAAM,GAAG,GAAG,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAE7C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CACL,8BACE,aAAI,SAAS,EAAC,cAAc,GAAG,EAC/B,eAAM,SAAS,EAAC,0BAA0B,YACxC,KAAC,gBAAgB,oBAAK,QAAQ,CAAC,iBAAiB,EAAI,GAC/C,EACP,eAAM,SAAS,EAAC,WAAW,YACzB,KAAC,MAAM,IAAC,OAAO,EAAC,yBAAyB,EAAC,IAAI,EAAE,GAAG,YAChD,aAAa,CAAC,QAAQ,CAAC,WAAW,CAAC,GAC7B,GACJ,IACN,CACJ,CAAC;AACJ,CAAC;AAED,eAAe,UAAU,CAAC","sourcesContent":["import { useIntl, FormattedMessage, getSiteConfig } from '@openedx/frontend-base';\nimport { Button } from '@openedx/paragon';\n\nimport messages from './messages';\n\ninterface Props {\n courseId?: string;\n unitId?: string;\n}\n\nfunction buildStudioUrl(courseId?: string, unitId?: string): string | null {\n const base = getSiteConfig().cmsBaseUrl;\n if (!base) {\n return null;\n }\n if (unitId) {\n return `${base}/container/${unitId}`;\n }\n if (courseId) {\n return `${base}/course/${courseId}`;\n }\n return null;\n}\n\nexport function StudioLink({ courseId, unitId }: Props) {\n const { formatMessage } = useIntl();\n const url = buildStudioUrl(courseId, unitId);\n\n if (!url) {\n return null;\n }\n\n return (\n <>\n <hr className=\"border-light\" />\n <span className=\"mr-2 mt-1 col-form-label\">\n <FormattedMessage {...messages.titleViewCourseIn} />\n </span>\n <span className=\"mx-1 my-1\">\n <Button variant=\"inverse-outline-primary\" href={url}>\n {formatMessage(messages.titleStudio)}\n </Button>\n </span>\n </>\n );\n}\n\nexport default StudioLink;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../../../../shell/header/course-bar/masquerade/data/api.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAkCpG,MAAM,UAAgB,oBAAoB,CAAC,QAAgB;;;QACzD,MAAM,GAAG,GAAG,GAAG,aAAa,EAAE,CAAC,UAAU,YAAY,QAAQ,aAAa,CAAC;QAC3E,MAAM,QAAQ,GAAG,MAAM,0BAA0B,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACjE,gFAAgF;QAChF,IAAI,CAAA,MAAA,QAAQ,CAAC,OAAO,0CAAE,WAAW,KAAI,QAAQ,CAAC,OAAO,CAAC,WAAW,KAAK,GAAG,EAAE,CAAC;YAC1E,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,qCAAqC,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE;gBAC1G,gBAAgB,EAAE,EAAE,eAAe,EAAE,GAAG,EAAE;aAC3C,CAAC,CAAC;YACH,MAAM,KAAK,CAAC;QACd,CAAC;QACD,OAAO,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;CAAA;AAED,MAAM,UAAgB,qBAAqB,CAAC,QAAgB,EAAE,OAA0B;;QACtF,MAAM,GAAG,GAAG,GAAG,aAAa,EAAE,CAAC,UAAU,YAAY,QAAQ,aAAa,CAAC;QAC3E,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACvE,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;CAAA","sourcesContent":["import { getSiteConfig, camelCaseObject, getAuthenticatedHttpClient } from '@openedx/frontend-base';\n\nexport type Role = 'staff' | 'student';\n\nexport interface ActiveMasqueradeData {\n role: Role,\n userName: string | null,\n userPartitionId: number | null,\n groupId: number | null,\n groupName: string | null,\n}\n\nexport interface MasqueradeOption {\n name: string,\n role: Role,\n userName?: string,\n groupId?: number,\n userPartitionId?: number,\n}\n\nexport interface MasqueradeStatus {\n success: boolean,\n error?: string,\n active: ActiveMasqueradeData,\n available: MasqueradeOption[],\n}\n\nexport interface MasqueradePayload {\n role?: Role,\n user_name?: string,\n group_id?: number,\n user_partition_id?: number,\n}\n\nexport async function getMasqueradeOptions(courseId: string): Promise<MasqueradeStatus> {\n const url = `${getSiteConfig().lmsBaseUrl}/courses/${courseId}/masquerade`;\n const response = await getAuthenticatedHttpClient().get(url, {});\n /* The LMS 302s to /login instead of returning 403 when masquerade is denied. */\n if (response.request?.responseURL && response.request.responseURL !== url) {\n const error = Object.assign(new Error(`Masquerade endpoint redirected to ${response.request.responseURL}`), {\n customAttributes: { httpErrorStatus: 403 },\n });\n throw error;\n }\n return camelCaseObject(response.data);\n}\n\nexport async function postMasqueradeOptions(courseId: string, payload: MasqueradePayload): Promise<MasqueradeStatus> {\n const url = `${getSiteConfig().lmsBaseUrl}/courses/${courseId}/masquerade`;\n const { data } = await getAuthenticatedHttpClient().post(url, payload);\n return camelCaseObject(data);\n}\n"]}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../../../../shell/header/course-bar/masquerade/data/api.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAkCpG,MAAM,UAAgB,oBAAoB,CAAC,QAAgB;;;QACzD,MAAM,GAAG,GAAG,GAAG,aAAa,EAAE,CAAC,UAAU,YAAY,QAAQ,aAAa,CAAC;QAC3E,MAAM,QAAQ,GAAG,MAAM,0BAA0B,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACjE,gFAAgF;QAChF,IAAI,CAAA,MAAA,QAAQ,CAAC,OAAO,0CAAE,WAAW,KAAI,QAAQ,CAAC,OAAO,CAAC,WAAW,KAAK,GAAG,EAAE,CAAC;YAC1E,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,qCAAqC,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE;gBAC1G,gBAAgB,EAAE,EAAE,eAAe,EAAE,GAAG,EAAE;aAC3C,CAAC,CAAC;YACH,MAAM,KAAK,CAAC;QACd,CAAC;QACD,OAAO,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;CAAA;AAED,MAAM,UAAgB,qBAAqB,CAAC,QAAgB,EAAE,OAA0B;;QACtF,MAAM,GAAG,GAAG,GAAG,aAAa,EAAE,CAAC,UAAU,YAAY,QAAQ,aAAa,CAAC;QAC3E,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACvE,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;CAAA","sourcesContent":["import { getSiteConfig, camelCaseObject, getAuthenticatedHttpClient } from '@openedx/frontend-base';\n\nexport type Role = 'staff' | 'student';\n\nexport interface ActiveMasqueradeData {\n role: Role;\n userName: string | null;\n userPartitionId: number | null;\n groupId: number | null;\n groupName: string | null;\n}\n\nexport interface MasqueradeOption {\n name: string;\n role: Role;\n userName?: string;\n groupId?: number;\n userPartitionId?: number;\n}\n\nexport interface MasqueradeStatus {\n success: boolean;\n error?: string;\n active: ActiveMasqueradeData;\n available: MasqueradeOption[];\n}\n\nexport interface MasqueradePayload {\n role?: Role;\n user_name?: string;\n group_id?: number;\n user_partition_id?: number;\n}\n\nexport async function getMasqueradeOptions(courseId: string): Promise<MasqueradeStatus> {\n const url = `${getSiteConfig().lmsBaseUrl}/courses/${courseId}/masquerade`;\n const response = await getAuthenticatedHttpClient().get(url, {});\n /* The LMS 302s to /login instead of returning 403 when masquerade is denied. */\n if (response.request?.responseURL && response.request.responseURL !== url) {\n const error = Object.assign(new Error(`Masquerade endpoint redirected to ${response.request.responseURL}`), {\n customAttributes: { httpErrorStatus: 403 },\n });\n throw error;\n }\n return camelCaseObject(response.data);\n}\n\nexport async function postMasqueradeOptions(courseId: string, payload: MasqueradePayload): Promise<MasqueradeStatus> {\n const url = `${getSiteConfig().lmsBaseUrl}/courses/${courseId}/masquerade`;\n const { data } = await getAuthenticatedHttpClient().post(url, payload);\n return camelCaseObject(data);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../../../../shell/header/course-bar/masquerade/hooks.ts"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useRef, useState } from 'react';\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport type { MessageDescriptor } from 'react-intl';\nimport { useLocation, useNavigate } from 'react-router-dom';\n\nimport {\n ActiveMasqueradeData,\n MasqueradeOption,\n MasqueradeStatus,\n MasqueradePayload,\n getMasqueradeOptions,\n postMasqueradeOptions,\n} from './data/api';\nimport {\n CourseHomeCourseMetadata,\n courseHomeCourseMetadataQueryKey,\n findActiveTab,\n getCourseHomeCourseMetadata,\n} from '../data/service';\nimport { isClientRoute } from '../utils';\nimport messages from './messages';\n\nconst defaultActive: ActiveMasqueradeData = {\n role: 'staff',\n groupId: null,\n groupName: null,\n userName: null,\n userPartitionId: null,\n};\n\nfunction toMasqueradePayload(option: MasqueradeOption): MasqueradePayload {\n const payload: MasqueradePayload = { role: option.role };\n if (option.groupId !== undefined && option.userPartitionId !== undefined) {\n payload.group_id = option.groupId;\n payload.user_partition_id = option.userPartitionId;\n }\n return payload;\n}\n\n/*\n * Whether `option` represents the active masquerade. Three shapes:\n * - userName defined: the \"Specific Student...\" prompt; active when the\n * server says we're masquerading as some specific user.\n * - groupId defined: a group option; active when the group ids match.\n * - neither: a plain role option (e.g. Staff); active when no group/user\n * is set.\n */\nexport function isOptionSelected(option: MasqueradeOption, active: ActiveMasqueradeData): boolean {\n if (option.role !== active.role) {\n return false;\n }\n if (option.userName !== undefined) {\n return active.userName !== null;\n }\n if (option.groupId !== undefined) {\n return option.groupId === active.groupId\n && option.userPartitionId === active.userPartitionId;\n }\n return active.userName === null && active.groupId === null;\n}\n\ninterface HttpishError {\n customAttributes?: { httpErrorStatus?: number },\n}\n\nfunction getHttpStatus(error: unknown): number | undefined {\n return (error as HttpishError | null)?.customAttributes?.httpErrorStatus;\n}\n\n/*\n * Anything other than a successful load with `success: true` hides the bar:\n * 403, 200 with `success: false`, network errors, 5xx, redirected requests.\n */\nfunction isQueryDenied(query: { isError: boolean, error: unknown, data: MasqueradeStatus | undefined }): boolean {\n if (query.isError) {\n return true;\n }\n return query.data !== undefined && !query.data.success;\n}\n\n/*\n * Errors are returned as MessageDescriptors when the frontend can pick the\n * message, or as a raw string when the server's `data.error` is more specific\n * than anything we'd hand-pick. formatErrorMessage handles both at the\n * render site.\n */\nexport type MasqueradeErrorMessage = MessageDescriptor | string;\n\nexport function formatErrorMessage(\n formatMessage: (descriptor: MessageDescriptor) => string,\n error: MasqueradeErrorMessage,\n): string {\n return typeof error === 'string' ? error : formatMessage(error);\n}\n\nfunction pickErrorMessage(\n mutation: { isError: boolean, error: unknown, data: MasqueradeStatus | undefined },\n): MasqueradeErrorMessage | null {\n if (mutation.isError) {\n return getHttpStatus(mutation.error) === 404\n ? messages.noStudentFound\n : messages.genericSubmitError;\n }\n if (mutation.data && !mutation.data.success) {\n return mutation.data.error || messages.genericSubmitError;\n }\n return null;\n}\n\nexport interface MasqueradeState {\n active: ActiveMasqueradeData,\n available: MasqueradeOption[],\n pendingOption: MasqueradeOption | null,\n showUserNameInput: boolean,\n userName: string,\n setUserName: (value: string) => void,\n select: (option: MasqueradeOption) => void,\n submitUserName: () => void,\n errorMessage: MasqueradeErrorMessage | null,\n isSubmitting: boolean,\n isLoading: boolean,\n isDenied: boolean,\n}\n\nexport function useMasqueradeState(courseId: string): MasqueradeState {\n const queryClient = useQueryClient();\n const navigate = useNavigate();\n const location = useLocation();\n /*\n * Tracks the option the user just clicked, so the toggle and active-marker\n * can update before the server confirms. Cleared once a mutation succeeds\n * (the server's active state becomes the truth) or replaced when the user\n * picks something else.\n */\n const [pendingOption, setPendingOption] = useState<MasqueradeOption | null>(null);\n const [userName, setUserName] = useState('');\n\n const query = useQuery({\n queryKey: ['masquerade', courseId],\n queryFn: () => getMasqueradeOptions(courseId),\n });\n\n const mutation = useMutation({\n mutationFn: (payload: MasqueradePayload) => postMasqueradeOptions(courseId, payload),\n onSuccess: async (data, payload) => {\n if (!data?.success) {\n /* Server rejected the pick. Clear the optimistic pending state so the\n * UI snaps back to the real active option, except for userName\n * submissions where the input must stay open for retry. */\n if (payload.user_name === undefined) {\n setPendingOption(null);\n }\n return;\n }\n\n queryClient.invalidateQueries();\n\n /* The course-tabs metadata is the source of truth for \"what pages this\n * user can see in this course.\" Fetch the post-masquerade tabs and\n * redirect to the first one if the current path no longer appears. */\n const meta = await queryClient.fetchQuery<CourseHomeCourseMetadata>({\n queryKey: courseHomeCourseMetadataQueryKey(courseId),\n queryFn: () => getCourseHomeCourseMetadata(courseId),\n });\n const fallback = meta.tabs[0];\n if (!fallback) {\n return;\n }\n const stillVisible = findActiveTab(meta.tabs, location.pathname);\n if (stillVisible) {\n return;\n }\n const targetPath = new URL(fallback.url).pathname;\n if (isClientRoute(targetPath)) {\n navigate(targetPath, { replace: true });\n } else {\n window.location.assign(fallback.url);\n }\n },\n onError: (_error, payload) => {\n /* Same as the !success branch: revert the optimistic pick, but keep the\n * userName input open so the user can fix a typo and retry. */\n if (payload.user_name === undefined) {\n setPendingOption(null);\n }\n },\n });\n\n const active = (query.data?.success && query.data.active) || defaultActive;\n const available = (query.data?.success && query.data.available) || [];\n\n /*\n * Seed the input from active.userName once, on the first successful query.\n * After that the input belongs to the user — refetches (e.g. triggered by\n * a masquerade change in another tab) must not clobber what they typed.\n */\n const hasSeededRef = useRef(false);\n useEffect(() => {\n if (hasSeededRef.current || !query.isSuccess) {\n return;\n }\n hasSeededRef.current = true;\n if (active.userName) {\n setUserName(active.userName);\n }\n }, [query.isSuccess, active.userName]);\n\n /*\n * Clear pendingOption once the refetched active state actually reflects it.\n * Clearing in onSuccess instead would briefly flash the old active state\n * between mutation success and the refetch landing.\n */\n useEffect(() => {\n if (pendingOption && isOptionSelected(pendingOption, active)) {\n setPendingOption(null);\n }\n }, [pendingOption, active]);\n\n const showUserNameInput = active.userName !== null\n || pendingOption?.userName !== undefined;\n\n const errorMessage = pickErrorMessage(mutation);\n const isDenied = isQueryDenied(query);\n /* Loading until the first response (success or failure) lands. */\n const isLoading = query.isLoading;\n\n const select = (option: MasqueradeOption) => {\n /* Clear any prior mutation error so it doesn't leak into the new selection. */\n mutation.reset();\n setPendingOption(option);\n if (option.userName !== undefined) {\n setUserName(option.userName);\n return;\n }\n mutation.mutate(toMasqueradePayload(option));\n };\n\n const submitUserName = () => {\n mutation.mutate({ role: 'student', user_name: userName });\n };\n\n return {\n active,\n available,\n pendingOption,\n showUserNameInput,\n userName,\n setUserName,\n select,\n submitUserName,\n errorMessage,\n isSubmitting: mutation.isPending,\n isLoading,\n isDenied,\n };\n}\n"]}
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../../../../shell/header/course-bar/masquerade/hooks.ts"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useRef, useState } from 'react';\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport type { MessageDescriptor } from 'react-intl';\nimport { useLocation, useNavigate } from 'react-router-dom';\n\nimport {\n ActiveMasqueradeData,\n MasqueradeOption,\n MasqueradeStatus,\n MasqueradePayload,\n getMasqueradeOptions,\n postMasqueradeOptions,\n} from './data/api';\nimport {\n CourseHomeCourseMetadata,\n courseHomeCourseMetadataQueryKey,\n findActiveTab,\n getCourseHomeCourseMetadata,\n} from '../data/service';\nimport { isClientRoute } from '../utils';\nimport messages from './messages';\n\nconst defaultActive: ActiveMasqueradeData = {\n role: 'staff',\n groupId: null,\n groupName: null,\n userName: null,\n userPartitionId: null,\n};\n\nfunction toMasqueradePayload(option: MasqueradeOption): MasqueradePayload {\n const payload: MasqueradePayload = { role: option.role };\n if (option.groupId !== undefined && option.userPartitionId !== undefined) {\n payload.group_id = option.groupId;\n payload.user_partition_id = option.userPartitionId;\n }\n return payload;\n}\n\n/*\n * Whether `option` represents the active masquerade. Three shapes:\n * - userName defined: the \"Specific Student...\" prompt; active when the\n * server says we're masquerading as some specific user.\n * - groupId defined: a group option; active when the group ids match.\n * - neither: a plain role option (e.g. Staff); active when no group/user\n * is set.\n */\nexport function isOptionSelected(option: MasqueradeOption, active: ActiveMasqueradeData): boolean {\n if (option.role !== active.role) {\n return false;\n }\n if (option.userName !== undefined) {\n return active.userName !== null;\n }\n if (option.groupId !== undefined) {\n return option.groupId === active.groupId\n && option.userPartitionId === active.userPartitionId;\n }\n return active.userName === null && active.groupId === null;\n}\n\ninterface HttpishError {\n customAttributes?: { httpErrorStatus?: number };\n}\n\nfunction getHttpStatus(error: unknown): number | undefined {\n return (error as HttpishError | null)?.customAttributes?.httpErrorStatus;\n}\n\n/*\n * Anything other than a successful load with `success: true` hides the bar:\n * 403, 200 with `success: false`, network errors, 5xx, redirected requests.\n */\nfunction isQueryDenied(query: { isError: boolean; error: unknown; data: MasqueradeStatus | undefined }): boolean {\n if (query.isError) {\n return true;\n }\n return query.data !== undefined && !query.data.success;\n}\n\n/*\n * Errors are returned as MessageDescriptors when the frontend can pick the\n * message, or as a raw string when the server's `data.error` is more specific\n * than anything we'd hand-pick. formatErrorMessage handles both at the\n * render site.\n */\nexport type MasqueradeErrorMessage = MessageDescriptor | string;\n\nexport function formatErrorMessage(\n formatMessage: (descriptor: MessageDescriptor) => string,\n error: MasqueradeErrorMessage,\n): string {\n return typeof error === 'string' ? error : formatMessage(error);\n}\n\nfunction pickErrorMessage(\n mutation: { isError: boolean; error: unknown; data: MasqueradeStatus | undefined },\n): MasqueradeErrorMessage | null {\n if (mutation.isError) {\n return getHttpStatus(mutation.error) === 404\n ? messages.noStudentFound\n : messages.genericSubmitError;\n }\n if (mutation.data && !mutation.data.success) {\n return mutation.data.error || messages.genericSubmitError;\n }\n return null;\n}\n\nexport interface MasqueradeState {\n active: ActiveMasqueradeData;\n available: MasqueradeOption[];\n pendingOption: MasqueradeOption | null;\n showUserNameInput: boolean;\n userName: string;\n setUserName: (value: string) => void;\n select: (option: MasqueradeOption) => void;\n submitUserName: () => void;\n errorMessage: MasqueradeErrorMessage | null;\n isSubmitting: boolean;\n isLoading: boolean;\n isDenied: boolean;\n}\n\nexport function useMasqueradeState(courseId: string): MasqueradeState {\n const queryClient = useQueryClient();\n const navigate = useNavigate();\n const location = useLocation();\n /*\n * Tracks the option the user just clicked, so the toggle and active-marker\n * can update before the server confirms. Cleared once a mutation succeeds\n * (the server's active state becomes the truth) or replaced when the user\n * picks something else.\n */\n const [pendingOption, setPendingOption] = useState<MasqueradeOption | null>(null);\n const [userName, setUserName] = useState('');\n\n const query = useQuery({\n queryKey: ['masquerade', courseId],\n queryFn: () => getMasqueradeOptions(courseId),\n });\n\n const mutation = useMutation({\n mutationFn: (payload: MasqueradePayload) => postMasqueradeOptions(courseId, payload),\n onSuccess: async (data, payload) => {\n if (!data?.success) {\n /* Server rejected the pick. Clear the optimistic pending state so the\n * UI snaps back to the real active option, except for userName\n * submissions where the input must stay open for retry. */\n if (payload.user_name === undefined) {\n setPendingOption(null);\n }\n return;\n }\n\n queryClient.invalidateQueries();\n\n /* The course-tabs metadata is the source of truth for \"what pages this\n * user can see in this course.\" Fetch the post-masquerade tabs and\n * redirect to the first one if the current path no longer appears. */\n const meta = await queryClient.fetchQuery<CourseHomeCourseMetadata>({\n queryKey: courseHomeCourseMetadataQueryKey(courseId),\n queryFn: () => getCourseHomeCourseMetadata(courseId),\n });\n const fallback = meta.tabs[0];\n if (!fallback) {\n return;\n }\n const stillVisible = findActiveTab(meta.tabs, location.pathname);\n if (stillVisible) {\n return;\n }\n const targetPath = new URL(fallback.url).pathname;\n if (isClientRoute(targetPath)) {\n navigate(targetPath, { replace: true });\n } else {\n window.location.assign(fallback.url);\n }\n },\n onError: (_error, payload) => {\n /* Same as the !success branch: revert the optimistic pick, but keep the\n * userName input open so the user can fix a typo and retry. */\n if (payload.user_name === undefined) {\n setPendingOption(null);\n }\n },\n });\n\n const active = (query.data?.success && query.data.active) || defaultActive;\n const available = (query.data?.success && query.data.available) || [];\n\n /*\n * Seed the input from active.userName once, on the first successful query.\n * After that the input belongs to the user — refetches (e.g. triggered by\n * a masquerade change in another tab) must not clobber what they typed.\n */\n const hasSeededRef = useRef(false);\n useEffect(() => {\n if (hasSeededRef.current || !query.isSuccess) {\n return;\n }\n hasSeededRef.current = true;\n if (active.userName) {\n setUserName(active.userName);\n }\n }, [query.isSuccess, active.userName]);\n\n /*\n * Clear pendingOption once the refetched active state actually reflects it.\n * Clearing in onSuccess instead would briefly flash the old active state\n * between mutation success and the refetch landing.\n */\n useEffect(() => {\n if (pendingOption && isOptionSelected(pendingOption, active)) {\n setPendingOption(null);\n }\n }, [pendingOption, active]);\n\n const showUserNameInput = active.userName !== null\n || pendingOption?.userName !== undefined;\n\n const errorMessage = pickErrorMessage(mutation);\n const isDenied = isQueryDenied(query);\n /* Loading until the first response (success or failure) lands. */\n const isLoading = query.isLoading;\n\n const select = (option: MasqueradeOption) => {\n /* Clear any prior mutation error so it doesn't leak into the new selection. */\n mutation.reset();\n setPendingOption(option);\n if (option.userName !== undefined) {\n setUserName(option.userName);\n return;\n }\n mutation.mutate(toMasqueradePayload(option));\n };\n\n const submitUserName = () => {\n mutation.mutate({ role: 'student', user_name: userName });\n };\n\n return {\n active,\n available,\n pendingOption,\n showUserNameInput,\n userName,\n setUserName,\n select,\n submitUserName,\n errorMessage,\n isSubmitting: mutation.isPending,\n isLoading,\n isDenied,\n };\n}\n"]}