Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Settings sidebar revamp #2266

Merged
merged 9 commits into from
Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/apps/settings/src/app/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
fetchFonts,
fetchFontsInstalled,
} from "shell/store/settings";
import { ResizableContainer } from "../../../../shell/components/ResizeableContainer";

// Makes sure that other apps using legacy theme does not get affected with the palette
const customTheme = createTheme(legacyTheme, {
Expand Down Expand Up @@ -116,7 +117,14 @@ export default connect((state) => ({
<ThemeProvider theme={customTheme}>
<section className={styles.Settings}>
<div className={styles.AppWrap}>
<SettingsNav />
<ResizableContainer
id="settingsNav"
defaultWidth={300}
minWidth={220}
maxWidth={360}
>
<SettingsNav />
</ResizableContainer>
<Box
className={styles.OverflowWrap}
sx={{
Expand Down
9 changes: 2 additions & 7 deletions src/apps/settings/src/app/App.less
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,10 @@

.Settings {
height: calc(100vh - 40px);
overflow: hidden;

.AppWrap {
display: grid;
grid-template-columns: 20vw auto;

@media only screen and (min-width: 2000px) {
grid-template-columns: 15vw auto;
}
display: flex;
height: 100%;

.OverflowWrap {
height: calc(100vh - 40px);
Expand Down
101 changes: 0 additions & 101 deletions src/apps/settings/src/app/components/Nav/SettingsNav.js

This file was deleted.

169 changes: 169 additions & 0 deletions src/apps/settings/src/app/components/Nav/SettingsNav.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
import { useState, useEffect, FC, useMemo } from "react";
import { useLocation } from "react-router";
import SettingsRoundedIcon from "@mui/icons-material/SettingsRounded";
import FormatSizeRoundedIcon from "@mui/icons-material/FormatSizeRounded";
import LanguageRoundedIcon from "@mui/icons-material/LanguageRounded";
import PaletteRoundedIcon from "@mui/icons-material/PaletteRounded";
import { Typography, Box } from "@mui/material";
import { startCase } from "lodash";

import { AppSideBar } from "../../../../../../shell/components/AppSidebar";
import { NavTree, TreeItem } from "../../../../../../shell/components/NavTree";
import {
useGetInstanceSettingsQuery,
useGetInstanceStylesCategoriesQuery,
} from "../../../../../../shell/services/instance";

const FONTS_CAT: TreeItem[] = [
{
label: "Installed fonts",
path: "/settings/fonts/installed",
icon: FormatSizeRoundedIcon,
children: [],
},
{
label: "Browse fonts",
path: "/settings/fonts/browse",
icon: FormatSizeRoundedIcon,
children: [],
},
];
const GLOBAL_META_CAT: TreeItem[] = [
{
label: "Head Tags",
path: "/settings/head",
icon: LanguageRoundedIcon,
children: [],
},
{
label: "Robots.txt",
path: "/settings/robots",
icon: LanguageRoundedIcon,
children: [],
},
];

export const SettingsNav = () => {
const location = useLocation();
const [keyword, setKeyword] = useState("");

const { data: rawInstanceSettings } = useGetInstanceSettingsQuery();
const { data: instanceStylesCategories } =
useGetInstanceStylesCategoriesQuery();

const instanceSettings: TreeItem[] = useMemo(() => {
if (rawInstanceSettings?.length) {
const categories: Set<string> = new Set();

rawInstanceSettings.forEach((setting) =>
categories.add(setting.category)
);

return Array.from(categories)?.map((category) => ({
label: startCase(category.replace(/_|-/g, " ")),
path: `/settings/instance/${category}`,
icon: SettingsRoundedIcon,
children: [],
}));
}

return [];
}, [rawInstanceSettings]);

const styleSettings: TreeItem[] = useMemo(() => {
if (instanceStylesCategories?.length) {
return [...instanceStylesCategories]
.sort((a, b) => (a.sort > b.sort ? 1 : -1))
.map((setting) => ({
label: setting.name,
path: `/settings/styles/${setting.ID}`,
icon: PaletteRoundedIcon,
children: [],
}));
}

return [];
}, [instanceStylesCategories]);

return (
<AppSideBar
data-cy="SettingsNav"
headerTitle="Settings"
mode="dark"
searchPlaceholder="Filter Settings"
withTitleButton={false}
onFilterChange={(keyword) => setKeyword(keyword.toLowerCase())}
>
<NavTree
id="InstanceSettingsTree"
HeaderComponent={<HeaderComponent title="Instance Settings" />}
tree={
keyword
? instanceSettings?.filter((setting) =>
setting.label.toLowerCase().includes(keyword)
)
: instanceSettings
}
selected={location.pathname}
/>
<Box pt={1.5}>
<NavTree
id="MetaTree"
HeaderComponent={<HeaderComponent title="Global Meta & SEO" />}
tree={
keyword
? GLOBAL_META_CAT?.filter((setting) =>
setting.label.toLowerCase().includes(keyword)
)
: GLOBAL_META_CAT
}
selected={location.pathname}
/>
</Box>
<Box pt={1.5}>
<NavTree
id="StylesTree"
HeaderComponent={<HeaderComponent title="Styles" />}
tree={
keyword
? styleSettings?.filter((setting) =>
setting.label.toLowerCase().includes(keyword)
)
: styleSettings
}
selected={location.pathname}
/>
</Box>
<Box pt={1.5}>
<NavTree
id="FontsTree"
HeaderComponent={<HeaderComponent title="Fonts" />}
tree={
keyword
? FONTS_CAT?.filter((setting) =>
setting.label.toLowerCase().includes(keyword)
)
: FONTS_CAT
}
selected={location.pathname}
/>
</Box>
</AppSideBar>
);
};

interface HeaderComponentProps {
finnar-bin marked this conversation as resolved.
Show resolved Hide resolved
title: string;
}
const HeaderComponent: FC<HeaderComponentProps> = ({ title }) => {
finnar-bin marked this conversation as resolved.
Show resolved Hide resolved
return (
<Typography
variant="body2"
textTransform="uppercase"
color="text.secondary"
sx={{ px: 1.5 }}
>
{title}
</Typography>
);
};
2 changes: 0 additions & 2 deletions src/apps/settings/src/app/components/Nav/index.js

This file was deleted.

2 changes: 2 additions & 0 deletions src/apps/settings/src/app/components/Nav/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { SettingsNav } from "./SettingsNav";
export { SettingsNav };
7 changes: 7 additions & 0 deletions src/shell/services/instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
Script,
Language,
Data,
StyleCategory,
} from "./types";
import { batchApiRequests } from "../../utility/batchApiRequests";

Expand Down Expand Up @@ -525,6 +526,11 @@ export const instanceApi = createApi({
}),
invalidatesTags: ["ContentNav"],
}),
// https://www.zesty.io/docs/instances/api-reference/web/stylesheets/variables/categories/#Get-Variable-Stylesheet-Categories
getInstanceStylesCategories: builder.query<StyleCategory[], void>({
query: () => `/web/stylesheets/variables/categories`,
transformResponse: getResponseData,
}),
}),
});

Expand Down Expand Up @@ -568,4 +574,5 @@ export const {
useGetContentItemVersionsQuery,
useUpdateContentItemMutation,
useDeleteContentItemMutation,
useGetInstanceStylesCategoriesQuery,
} = instanceApi;
11 changes: 11 additions & 0 deletions src/shell/services/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -464,3 +464,14 @@ export interface InstalledApp {
updatedAt: string;
url: string;
}

export interface StyleCategory {
finnar-bin marked this conversation as resolved.
Show resolved Hide resolved
ID: number;
name: string;
icon: string;
sort: number;
options: any;
description: string;
createdAt: string;
updatedAt: string;
}