* refactor: use React Query to load waffle flags * test: add test case * fix: more clear handling of data loading and fallbacks * refactor: simplify handling of useReactMarkdownEditor * test: use new mockWaffleFlags() helper * test: simplify test mocks in hooks.test.js * refactor: avoid duplicating flag names, clarify how defaults work
93 lines
2.8 KiB
TypeScript
93 lines
2.8 KiB
TypeScript
import { getConfig } from '@edx/frontend-platform';
|
|
import { useIntl } from '@edx/frontend-platform/i18n';
|
|
import { StudioHeader } from '@edx/frontend-component-header';
|
|
import { type Container, useToggle } from '@openedx/paragon';
|
|
|
|
import { useWaffleFlags } from '../data/apiHooks';
|
|
import { SearchModal } from '../search-modal';
|
|
import { useContentMenuItems, useSettingMenuItems, useToolsMenuItems } from './hooks';
|
|
import messages from './messages';
|
|
|
|
type ContainerPropsType = React.ComponentProps<typeof Container>;
|
|
|
|
interface HeaderProps {
|
|
contextId?: string,
|
|
number?: string,
|
|
org?: string,
|
|
title?: string,
|
|
isHiddenMainMenu?: boolean,
|
|
isLibrary?: boolean,
|
|
containerProps?: ContainerPropsType,
|
|
}
|
|
|
|
const Header = ({
|
|
contextId = '',
|
|
org = '',
|
|
number = '',
|
|
title = '',
|
|
isHiddenMainMenu = false,
|
|
isLibrary = false,
|
|
containerProps = {},
|
|
}: HeaderProps) => {
|
|
const intl = useIntl();
|
|
const waffleFlags = useWaffleFlags();
|
|
|
|
const [isShowSearchModalOpen, openSearchModal, closeSearchModal] = useToggle(false);
|
|
|
|
const studioBaseUrl = getConfig().STUDIO_BASE_URL;
|
|
const meiliSearchEnabled = [true, 'true'].includes(getConfig().MEILISEARCH_ENABLED);
|
|
|
|
const contentMenuItems = useContentMenuItems(contextId);
|
|
const settingMenuItems = useSettingMenuItems(contextId);
|
|
const toolsMenuItems = useToolsMenuItems(contextId);
|
|
const mainMenuDropdowns = !isLibrary ? [
|
|
{
|
|
id: `${intl.formatMessage(messages['header.links.content'])}-dropdown-menu`,
|
|
buttonTitle: intl.formatMessage(messages['header.links.content']),
|
|
items: contentMenuItems,
|
|
},
|
|
{
|
|
id: `${intl.formatMessage(messages['header.links.settings'])}-dropdown-menu`,
|
|
buttonTitle: intl.formatMessage(messages['header.links.settings']),
|
|
items: settingMenuItems,
|
|
},
|
|
{
|
|
id: `${intl.formatMessage(messages['header.links.tools'])}-dropdown-menu`,
|
|
buttonTitle: intl.formatMessage(messages['header.links.tools']),
|
|
items: toolsMenuItems,
|
|
},
|
|
] : [];
|
|
|
|
const getOutlineLink = () => {
|
|
if (isLibrary) {
|
|
return `/library/${contextId}`;
|
|
}
|
|
return waffleFlags.useNewCourseOutlinePage ? `/course/${contextId}` : `${studioBaseUrl}/course/${contextId}`;
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<StudioHeader
|
|
org={org}
|
|
number={number}
|
|
title={title}
|
|
isHiddenMainMenu={isHiddenMainMenu}
|
|
mainMenuDropdowns={mainMenuDropdowns}
|
|
outlineLink={getOutlineLink()}
|
|
searchButtonAction={meiliSearchEnabled ? openSearchModal : undefined}
|
|
containerProps={containerProps}
|
|
isNewHomePage={waffleFlags.useNewHomePage}
|
|
/>
|
|
{meiliSearchEnabled && (
|
|
<SearchModal
|
|
isOpen={isShowSearchModalOpen}
|
|
courseId={isLibrary ? undefined : contextId}
|
|
onClose={closeSearchModal}
|
|
/>
|
|
)}
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default Header;
|