Skip to content

Commit

Permalink
[183] Provide a dedicated hook to manipulate the palette
Browse files Browse the repository at this point in the history
Bug: #183
Signed-off-by: Stéphane Bégaudeau <stephane.begaudeau@gmail.com>
  • Loading branch information
sbegaudeau committed Jun 28, 2023
1 parent 43e4342 commit 5cb90c9
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 30 deletions.
38 changes: 37 additions & 1 deletion frontend/svalyn-studio-app/src/palette/DefaultPaletteActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@
*/

import CorporateFareIcon from '@mui/icons-material/CorporateFare';
import HelpIcon from '@mui/icons-material/Help';
import HomeIcon from '@mui/icons-material/Home';
import HubIcon from '@mui/icons-material/Hub';
import { PaletteNavigationAction } from './Palette.types';
import NotificationsNoneIcon from '@mui/icons-material/NotificationsNone';
import SettingsIcon from '@mui/icons-material/Settings';
import { PaletteAction, PaletteNavigationAction } from './Palette.types';

export const goToHome: PaletteNavigationAction = {
type: 'navigation-action',
Expand All @@ -45,3 +48,36 @@ export const goToNewOrganization: PaletteNavigationAction = {
label: 'New organization',
to: '/new/organization',
};

export const goToNotifications: PaletteNavigationAction = {
type: 'navigation-action',
id: 'go-to-notifications',
icon: <NotificationsNoneIcon fontSize="small" />,
label: 'Notifications',
to: '/notifications',
};

export const goToSettings: PaletteNavigationAction = {
type: 'navigation-action',
id: 'go-to-settings',
icon: <SettingsIcon fontSize="small" />,
label: 'Settings',
to: '/settings',
};

export const goToHelp: PaletteNavigationAction = {
type: 'navigation-action',
id: 'go-to-help',
icon: <HelpIcon fontSize="small" />,
label: 'Help',
to: '/help',
};

export const actions: PaletteAction[] = [
goToHome,
goToDomains,
goToNewOrganization,
goToNotifications,
goToSettings,
goToHelp,
];
4 changes: 1 addition & 3 deletions frontend/svalyn-studio-app/src/palette/PaletteProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,14 @@
*/

import { useEffect, useState } from 'react';
import { goToDomains, goToHome, goToNewOrganization } from './DefaultPaletteActions';
import { actions } from './DefaultPaletteActions';
import { Palette } from './Palette';
import { PaletteAction } from './Palette.types';
import { PaletteContext } from './PaletteContext';
import { PaletteContextValue } from './PaletteContext.types';
import { PaletteProviderProps, PaletteProviderState } from './PaletteProvider.types';

export const PaletteProvider = ({ children }: PaletteProviderProps) => {
const actions: PaletteAction[] = [goToHome, goToDomains, goToNewOrganization];

const [state, setState] = useState<PaletteProviderState>({ actions, open: false });

useEffect(() => {
Expand Down
42 changes: 42 additions & 0 deletions frontend/svalyn-studio-app/src/palette/usePalette.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2023 Stéphane Bégaudeau.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
* LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

import { useContext, useEffect, useState } from 'react';
import { actions } from './DefaultPaletteActions';
import { PaletteAction } from './Palette.types';
import { PaletteContext } from './PaletteContext';
import { PaletteContextValue } from './PaletteContext.types';
import { UsePalette, UsePaletteState } from './usePalette.types';

export const usePalette = (initialActions: PaletteAction[] = actions): UsePalette => {
const [state, setState] = useState<UsePaletteState>({
actions: initialActions,
});

const { setActions }: PaletteContextValue = useContext<PaletteContextValue>(PaletteContext);
useEffect(() => {
setActions(state.actions);

return () => setActions(actions);
}, [state.actions]);

return {
setActions: (actions: PaletteAction[]) => setState((prevState) => ({ ...prevState, actions })),
};
};
28 changes: 28 additions & 0 deletions frontend/svalyn-studio-app/src/palette/usePalette.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2023 Stéphane Bégaudeau.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
* LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

import { PaletteAction } from './Palette.types';

export interface UsePaletteState {
actions: PaletteAction[];
}

export interface UsePalette {
setActions: (actions: PaletteAction[]) => void;
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,18 @@ import Tab from '@mui/material/Tab';
import Tabs from '@mui/material/Tabs';
import Toolbar from '@mui/material/Toolbar';
import Typography from '@mui/material/Typography';
import React, { useContext, useEffect, useState } from 'react';
import React, { useEffect, useState } from 'react';
import { generatePath, matchPath, useLocation, useNavigate } from 'react-router-dom';
import { goToDomains, goToHome, goToNewOrganization } from '../../palette/DefaultPaletteActions';
import {
goToDomains,
goToHelp,
goToHome,
goToNewOrganization,
goToNotifications,
goToSettings,
} from '../../palette/DefaultPaletteActions';
import { PaletteSimpleAction } from '../../palette/Palette.types';
import { PaletteContext } from '../../palette/PaletteContext';
import { PaletteContextValue } from '../../palette/PaletteContext.types';
import { usePalette } from '../../palette/usePalette';
import { NewProjectDialog } from './NewProjectDialog';
import { OrganizationViewTabPanelProps, OrganizationViewTabPanelState } from './OrganizationViewTabPanel.types';
import { OrganizationDashboard } from './dashboard/OrganizationDashboard';
Expand Down Expand Up @@ -108,19 +114,14 @@ export const OrganizationViewTabPanel = ({ organization }: OrganizationViewTabPa
setState((prevState) => ({ ...prevState, newProjectDialogOpen: true }));
const closeNewProjectDialog = () => setState((prevState) => ({ ...prevState, newProjectDialogOpen: false }));

const { setActions }: PaletteContextValue = useContext<PaletteContextValue>(PaletteContext);
useEffect(() => {
const goToNewProject: PaletteSimpleAction = {
type: 'simple-action',
id: 'create-project',
icon: <ClassIcon fontSize="small" />,
label: 'New project',
handle: () => setState((prevState) => ({ ...prevState, newProjectDialogOpen: true })),
};
setActions([goToHome, goToDomains, goToNewProject]);

return () => setActions([goToHome, goToDomains, goToNewOrganization]);
}, []);
const goToNewProject: PaletteSimpleAction = {
type: 'simple-action',
id: 'create-project',
icon: <ClassIcon fontSize="small" />,
label: 'New project',
handle: () => setState((prevState) => ({ ...prevState, newProjectDialogOpen: true })),
};
usePalette([goToHome, goToDomains, goToNewOrganization, goToNewProject, goToNotifications, goToSettings, goToHelp]);

return (
<>
Expand Down
15 changes: 6 additions & 9 deletions frontend/svalyn-studio-app/src/views/project/ProjectView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,12 @@ import { gql, useQuery } from '@apollo/client';
import CorporateFareIcon from '@mui/icons-material/CorporateFare';
import Box from '@mui/material/Box';
import Link from '@mui/material/Link';
import { useContext, useEffect, useState } from 'react';
import { useEffect, useState } from 'react';
import { Link as RouterLink, matchPath, useLocation, useParams } from 'react-router-dom';
import { Navbar } from '../../navbars/Navbar';
import { goToDomains, goToHome, goToNewOrganization } from '../../palette/DefaultPaletteActions';
import { goToDomains, goToHelp, goToHome, goToNotifications, goToSettings } from '../../palette/DefaultPaletteActions';
import { PaletteNavigationAction } from '../../palette/Palette.types';
import { PaletteContext } from '../../palette/PaletteContext';
import { PaletteContextValue } from '../../palette/PaletteContext.types';
import { usePalette } from '../../palette/usePalette';
import { ErrorSnackbar } from '../../snackbar/ErrorSnackbar';
import { NotFoundView } from '../notfound/NotFoundView';
import { ProjectDrawer } from './ProjectDrawer';
Expand Down Expand Up @@ -88,7 +87,7 @@ export const ProjectView = () => {
const variables: GetProjectVariables = { identifier: projectIdentifier ?? '' };
const { loading, data, error } = useQuery<GetProjectData, GetProjectVariables>(getProjectQuery, { variables });

const { setActions }: PaletteContextValue = useContext<PaletteContextValue>(PaletteContext);
const { setActions } = usePalette();

useEffect(() => {
if (!loading) {
Expand All @@ -99,22 +98,20 @@ export const ProjectView = () => {
if (project) {
setState((prevState) => ({ ...prevState, project }));

const goToOrganization: PaletteNavigationAction = {
const backToOrganization: PaletteNavigationAction = {
type: 'navigation-action',
id: 'go-to-organization',
icon: <CorporateFareIcon fontSize="small" />,
label: project.organization.name,
to: `/orgs/${project.organization.identifier}`,
};
setActions([goToHome, goToDomains, goToOrganization]);
setActions([goToHome, goToDomains, backToOrganization, goToNotifications, goToSettings, goToHelp]);
}
}
if (error) {
setState((prevState) => ({ ...prevState, message: error.message }));
}
}

return () => setActions([goToHome, goToDomains, goToNewOrganization]);
}, [loading, data, error]);

useEffect(() => {}, []);
Expand Down

0 comments on commit 5cb90c9

Please sign in to comment.