105 lines
3.0 KiB
TypeScript
105 lines
3.0 KiB
TypeScript
import { createContext, useContext, useMemo } from 'react';
|
|
import { getConfig } from '@edx/frontend-platform';
|
|
import { Info, Plus, Tag } from '@openedx/paragon/icons';
|
|
|
|
import type { SidebarPage } from '@src/generic/sidebar';
|
|
|
|
import { InfoSidebar } from './unit-info/InfoSidebar';
|
|
import { AddSidebar } from './AddSidebar';
|
|
import { UnitAlignSidebar } from './UnitAlignSidebar';
|
|
import { useUnitSidebarContext } from './UnitSidebarContext';
|
|
import messages from './messages';
|
|
|
|
export type UnitSidebarPages = {
|
|
info: SidebarPage;
|
|
add?: SidebarPage;
|
|
align?: SidebarPage;
|
|
};
|
|
|
|
const getUnitSidebarPages = (readOnly: boolean, hasComponentSelected: boolean) => {
|
|
const showAlignSidebar = getConfig().ENABLE_TAGGING_TAXONOMY_PAGES === 'true';
|
|
|
|
return {
|
|
info: {
|
|
component: InfoSidebar,
|
|
icon: Info,
|
|
title: messages.sidebarButtonInfo,
|
|
},
|
|
...(!readOnly && {
|
|
add: {
|
|
component: AddSidebar,
|
|
icon: Plus,
|
|
title: messages.sidebarButtonAdd,
|
|
disabled: hasComponentSelected,
|
|
tooltip: hasComponentSelected ? messages.sidebarDisabledAddTooltip : undefined,
|
|
},
|
|
}),
|
|
...(showAlignSidebar && {
|
|
align: {
|
|
component: UnitAlignSidebar,
|
|
icon: Tag,
|
|
title: messages.sidebarButtonAlign,
|
|
},
|
|
}),
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Context for the Unit Sidebar Pages.
|
|
*
|
|
* This could be used in plugins to add new pages to the sidebar.
|
|
*
|
|
* @example
|
|
*
|
|
* ```tsx
|
|
* export function UnitOutlineSidebarWrapper(
|
|
* { component, pluginProps }: { component: React.ReactNode, pluginProps: UnitOutlineAspectsPageProps},
|
|
* ) {
|
|
* const sidebarPages = useUnitSidebarPagesContext();
|
|
* const AnalyticsPage = useCallback(() => <UnitOutlineAspectsPage {...pluginProps} />, [pluginProps]);
|
|
*
|
|
* const overridedPages = useMemo(() => ({
|
|
* ...sidebarPages,
|
|
* analytics: {
|
|
* component: AnalyticsPage,
|
|
* icon: AutoGraph,
|
|
* title: messages.analyticsLabel,
|
|
* },
|
|
* }), [sidebarPages, AnalyticsPage]);
|
|
*
|
|
* return (
|
|
* <UnitSidebarPagesContext.Provider value={overridedPages}>
|
|
* {component}
|
|
* </UnitSidebarPagesContext.Provider>
|
|
* );
|
|
* }
|
|
*/
|
|
export const UnitSidebarPagesContext = createContext<UnitSidebarPages | undefined>(undefined);
|
|
|
|
type UnitSidebarPagesProviderProps = {
|
|
children: React.ReactNode;
|
|
};
|
|
|
|
export const UnitSidebarPagesProvider = ({ children }: UnitSidebarPagesProviderProps) => {
|
|
const { readOnly, selectedComponentId } = useUnitSidebarContext();
|
|
|
|
const hasComponentSelected = selectedComponentId !== undefined;
|
|
|
|
const sidebarPages = useMemo(
|
|
() => getUnitSidebarPages(readOnly, hasComponentSelected),
|
|
[readOnly, hasComponentSelected],
|
|
);
|
|
|
|
return (
|
|
<UnitSidebarPagesContext.Provider value={sidebarPages}>
|
|
{children}
|
|
</UnitSidebarPagesContext.Provider>
|
|
);
|
|
};
|
|
|
|
export const useUnitSidebarPagesContext = (): UnitSidebarPages => {
|
|
const ctx = useContext(UnitSidebarPagesContext);
|
|
if (ctx === undefined) { throw new Error('useUnitSidebarPages must be used within an UnitSidebarPagesProvider'); }
|
|
return ctx;
|
|
};
|