@octopusdeploy/design-system-components
Version:
The design systems component library.
136 lines (135 loc) • 8.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Level1PageLayout = Level1PageLayout;
const jsx_runtime_1 = require("react/jsx-runtime");
const css_1 = require("@emotion/css");
const design_system_tokens_1 = require("@octopusdeploy/design-system-tokens");
const hooks_1 = require("../../hooks");
const Callout_1 = require("../Callout/Callout");
const ErrorSummary_1 = require("../ErrorSummary");
const Level1PageHeader_1 = require("../Level1PageHeader");
const Progress_1 = require("../Progress");
const AdvancedFilterPanel_1 = require("./AdvancedFilterPanel");
const Filters_1 = require("./Filters");
const useAdvancedFiltersVisibility_1 = require("./useAdvancedFiltersVisibility");
/**
* The `Level1PageLayout` component has pre-determined slots for `Errors`, `Callout`, `Header`, `Pagination`, and `Filters`.
* It is designed to provide a consistent layout for pages with a single content area and optional filters and pagination controls.
*/
function Level1PageLayout({ header, busy = false, callout, errors, isFullWidth, ...contentProps }) {
const content = contentProps.children;
const filters = contentProps.filters;
const pagination = contentProps.pagination;
const isSmallScreen = (0, hooks_1.useIsLegacySmallScreen)();
const isLargerThanIPad = (0, hooks_1.useIsLargerThanIpadResolution)();
const [isAdvancedFiltersVisible, setIsAdvancedFiltersVisible] = (0, useAdvancedFiltersVisibility_1.useAdvancedFiltersVisibility)(filters?.advancedFilters);
const paginationAtBottom = pagination && pagination.placement !== "top";
const paginationAtTop = pagination && pagination.placement !== "bottom";
const hasAdvancedFilters = filters?.advancedFilters !== undefined;
const hasFilters = (filters?.inputs && filters.inputs.length > 0) || hasAdvancedFilters;
const sidebar = contentProps.sidebar;
const hasFilterAndPaginationSection = hasFilters || filters?.filtersSummary !== undefined || paginationAtTop;
const hasErrorPanelAndCalloutSection = (errors && errors.length > 0) || callout !== undefined;
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, css_1.cx)(pageContentStyles.container, { [pageContentStyles.containerHasPaddingMobile]: !isLargerThanIPad, [pageContentStyles.containerMaxWidth]: !isFullWidth }), children: [(0, jsx_runtime_1.jsx)("div", { className: pageContentStyles.progressBarContainer, children: (0, jsx_runtime_1.jsx)(Progress_1.LinearProgress, { variant: "indeterminate", show: busy }) }), (0, jsx_runtime_1.jsx)(Level1PageHeader_1.Level1PageHeader, { breadcrumbs: header.breadcrumbs, title: header.title, primaryAction: header.primaryAction, actions: header.pageActions, overflowActions: header.overflowActions, titleBadge: header.badge, titleAccessory: header.contextSelector }), (0, jsx_runtime_1.jsxs)("div", { className: (0, css_1.cx)(pageContentStyles.contentBelowHeader, pageContentStyles.smallBottomPaddingContainer, { [pageContentStyles.largeBottomPaddingContainer]: !isLargerThanIPad }), children: [hasErrorPanelAndCalloutSection && ((0, jsx_runtime_1.jsxs)("div", { className: pageContentStyles.errorPanelAndCalloutSection, children: [errors?.map((error, index) => ((0, jsx_runtime_1.jsx)(ErrorSummary_1.ErrorSummary, { error: error }, index))), isCustomCallout(callout) && callout.content, isDefaultCallout(callout) && (callout.title ? (0, jsx_runtime_1.jsx)(Callout_1.Callout, { ...callout, title: callout.title, canClose: !!callout.onClose }) : (0, jsx_runtime_1.jsx)(Callout_1.Callout, { ...callout, hideTitle: true, canClose: !!callout.onClose }))] })), hasFilterAndPaginationSection && ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { className: pageContentStyles.filtersAndPaginationRow, children: [hasFilters && ((0, jsx_runtime_1.jsx)(Filters_1.Filters, { inputs: filters.inputs, showAdvancedFiltersToggle: hasAdvancedFilters, isAdvancedFiltersVisible: isAdvancedFiltersVisible, onAdvancedFiltersVisibilityChanged: setIsAdvancedFiltersVisible, activeFilterCount: filters.advancedFilters?.activeFilterCount })), paginationAtTop && pagination.ui] }), filters?.filtersSummary && (0, jsx_runtime_1.jsx)(Filters_1.FiltersSummary, { summary: filters.filtersSummary })] })), (0, jsx_runtime_1.jsxs)("div", { className: (0, css_1.cx)(pageContentStyles.sectionsWithSidebars, {
[pageContentStyles.sectionsWithSidebarsVertical]: isSmallScreen,
}), children: [filters?.advancedFilters && isAdvancedFiltersVisible && ((0, jsx_runtime_1.jsx)(AdvancedFilterPanel_1.AdvancedFilterPanel, { content: filters.advancedFilters.content, onResetFilter: filters.advancedFilters.onResetFilter, isResetEnabled: filters.advancedFilters.hasUserSelectedValues, parentOrientation: isSmallScreen ? "column" : "row" })), (0, jsx_runtime_1.jsx)("div", { className: pageContentStyles.contentBox, children: content }), sidebar && (0, jsx_runtime_1.jsx)(Sidebar, { content: sidebar, parentOrientation: isSmallScreen ? "column" : "row" })] }), paginationAtBottom && (0, jsx_runtime_1.jsx)("div", { className: pageContentStyles.footerPaginationSection, children: pagination.ui })] })] }));
}
function isCustomCallout(callout) {
return !!callout && "type" in callout && callout.type === "custom";
}
function isDefaultCallout(callout) {
return !!callout && "messageState" in callout;
}
function getCalloutTitleProps(title) {
if (!title) {
return { title, hideTitle: true };
}
return {
title,
hideTitle: false,
};
}
const pageContentStyles = {
container: (0, css_1.css)({
display: "flex",
position: "relative",
flexDirection: "column",
font: design_system_tokens_1.text.body.regular.medium,
marginLeft: "auto",
marginRight: "auto",
padding: design_system_tokens_1.space[32],
}),
containerMaxWidth: (0, css_1.css)({
maxWidth: 1280,
}),
containerHasPaddingMobile: (0, css_1.css)({
padding: design_system_tokens_1.space[16],
}),
contentBelowHeader: (0, css_1.css)({
display: "flex",
flexDirection: "column",
gap: design_system_tokens_1.space[16],
}),
smallBottomPaddingContainer: (0, css_1.css)({
paddingBottom: design_system_tokens_1.space[16],
}),
largeBottomPaddingContainer: (0, css_1.css)({
paddingBottom: design_system_tokens_1.space[32],
}),
progressBarContainer: (0, css_1.css)({
paddingBottom: design_system_tokens_1.space[8],
position: "absolute",
width: "100%",
top: 0,
left: 0,
}),
errorPanelAndCalloutSection: (0, css_1.css)({
display: "flex",
flexDirection: "column",
gap: design_system_tokens_1.space[8],
}),
filtersAndPaginationRow: (0, css_1.css)({
display: "flex",
gap: design_system_tokens_1.space[8],
justifyContent: "space-between",
// Bottom-aligned to keep the pagination controls level with the filters' input row, which
// sits at the bottom of the filter block when the filter inputs have stacked labels.
alignItems: "flex-end",
}),
sectionsWithSidebars: (0, css_1.css)({
display: "flex",
flex: 1,
color: design_system_tokens_1.themeTokens.color.text.primary,
}),
sectionsWithSidebarsVertical: (0, css_1.css)({
flexDirection: "column",
}),
contentBox: (0, css_1.css)({
flex: 1,
minWidth: 0,
}),
footerPaginationSection: (0, css_1.css)({
display: "flex",
justifyContent: "flex-end",
}),
};
function Sidebar({ content, parentOrientation }) {
return ((0, jsx_runtime_1.jsx)("div", { className: (0, css_1.cx)(sidebarStyles.root, {
[sidebarStyles.inRow]: parentOrientation === "row",
[sidebarStyles.inColumn]: parentOrientation === "column",
}), children: content }));
}
const sidebarStyles = {
root: (0, css_1.css)({
padding: `0 ${design_system_tokens_1.space[16]}`,
}),
inRow: (0, css_1.css)({
width: "17.5rem",
border: `1px solid ${design_system_tokens_1.themeTokens.color.border.primary}`,
borderTopRightRadius: design_system_tokens_1.borderRadius.medium,
borderBottomRightRadius: design_system_tokens_1.borderRadius.medium,
}),
inColumn: (0, css_1.css)({
borderTop: `1px solid ${design_system_tokens_1.themeTokens.color.border.primary}`,
}),
};