feat(user-interface): introduce optimistic response
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import CssBaseline from '@mui/material/CssBaseline';
|
import CssBaseline from '@mui/material/CssBaseline';
|
||||||
import { ThemeProvider as BaseThemeProvider } from '@mui/material/styles';
|
import { ThemeProvider as BaseThemeProvider } from '@mui/material/styles';
|
||||||
|
import clone from 'lodash/clone';
|
||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
import set from 'lodash/set';
|
import set from 'lodash/set';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
@@ -13,16 +14,19 @@ type ThemeProviderProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const customizeTheme = (defaultTheme: typeof theme, config: IJSONObject) => {
|
const customizeTheme = (defaultTheme: typeof theme, config: IJSONObject) => {
|
||||||
|
// `clone` is needed so that the new theme reference triggers re-render
|
||||||
|
const shallowDefaultTheme = clone(defaultTheme);
|
||||||
|
|
||||||
for (const key in config) {
|
for (const key in config) {
|
||||||
const value = config[key];
|
const value = config[key];
|
||||||
const exists = get(defaultTheme, key);
|
const exists = get(defaultTheme, key);
|
||||||
|
|
||||||
if (exists) {
|
if (exists) {
|
||||||
set(defaultTheme, key, value);
|
set(shallowDefaultTheme, key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return defaultTheme;
|
return shallowDefaultTheme;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ThemeProvider = ({
|
const ThemeProvider = ({
|
||||||
|
@@ -7,6 +7,7 @@ import LoadingButton from '@mui/lab/LoadingButton';
|
|||||||
import { useSnackbar } from 'notistack';
|
import { useSnackbar } from 'notistack';
|
||||||
import merge from 'lodash/merge';
|
import merge from 'lodash/merge';
|
||||||
|
|
||||||
|
import { GET_CONFIG } from 'graphql/queries/get-config.ee';
|
||||||
import { UPDATE_CONFIG } from 'graphql/mutations/update-config.ee';
|
import { UPDATE_CONFIG } from 'graphql/mutations/update-config.ee';
|
||||||
import useConfig from 'hooks/useConfig';
|
import useConfig from 'hooks/useConfig';
|
||||||
import PageTitle from 'components/PageTitle';
|
import PageTitle from 'components/PageTitle';
|
||||||
@@ -49,9 +50,7 @@ const defaultValues = {
|
|||||||
|
|
||||||
export default function UserInterface(): React.ReactElement {
|
export default function UserInterface(): React.ReactElement {
|
||||||
const formatMessage = useFormatMessage();
|
const formatMessage = useFormatMessage();
|
||||||
const [updateConfig, { loading }] = useMutation(UPDATE_CONFIG, {
|
const [updateConfig, { loading }] = useMutation(UPDATE_CONFIG);
|
||||||
refetchQueries: ['GetConfig'],
|
|
||||||
});
|
|
||||||
const { config, loading: configLoading } = useConfig([
|
const { config, loading: configLoading } = useConfig([
|
||||||
'title',
|
'title',
|
||||||
'palette.primary.main',
|
'palette.primary.main',
|
||||||
@@ -61,15 +60,14 @@ export default function UserInterface(): React.ReactElement {
|
|||||||
]);
|
]);
|
||||||
const { enqueueSnackbar } = useSnackbar();
|
const { enqueueSnackbar } = useSnackbar();
|
||||||
const configWithDefaults = merge(
|
const configWithDefaults = merge(
|
||||||
|
{},
|
||||||
defaultValues,
|
defaultValues,
|
||||||
nestObject<UserInterface>(config)
|
nestObject<UserInterface>(config)
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleUserInterfaceUpdate = async (uiData: Partial<UserInterface>) => {
|
const handleUserInterfaceUpdate = async (uiData: Partial<UserInterface>) => {
|
||||||
try {
|
try {
|
||||||
await updateConfig({
|
const input = {
|
||||||
variables: {
|
|
||||||
input: {
|
|
||||||
title: uiData?.title,
|
title: uiData?.title,
|
||||||
'palette.primary.main': getPrimaryMainColor(
|
'palette.primary.main': getPrimaryMainColor(
|
||||||
uiData?.palette?.primary.main
|
uiData?.palette?.primary.main
|
||||||
@@ -81,7 +79,50 @@ export default function UserInterface(): React.ReactElement {
|
|||||||
uiData?.palette?.primary.light
|
uiData?.palette?.primary.light
|
||||||
),
|
),
|
||||||
'logo.svgData': uiData?.logo?.svgData,
|
'logo.svgData': uiData?.logo?.svgData,
|
||||||
|
};
|
||||||
|
|
||||||
|
await updateConfig({
|
||||||
|
variables: {
|
||||||
|
input,
|
||||||
},
|
},
|
||||||
|
optimisticResponse: {
|
||||||
|
updateConfig: input,
|
||||||
|
},
|
||||||
|
update: async function (cache, { data: { updateConfig } }) {
|
||||||
|
const newConfigWithDefaults = merge({}, defaultValues, updateConfig);
|
||||||
|
|
||||||
|
cache.writeQuery({
|
||||||
|
query: GET_CONFIG,
|
||||||
|
data: {
|
||||||
|
getConfig: newConfigWithDefaults,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
cache.writeQuery({
|
||||||
|
query: GET_CONFIG,
|
||||||
|
data: {
|
||||||
|
getConfig: newConfigWithDefaults,
|
||||||
|
},
|
||||||
|
variables: {
|
||||||
|
keys: ['logo.svgData'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
cache.writeQuery({
|
||||||
|
query: GET_CONFIG,
|
||||||
|
data: {
|
||||||
|
getConfig: newConfigWithDefaults,
|
||||||
|
},
|
||||||
|
variables: {
|
||||||
|
keys: [
|
||||||
|
'title',
|
||||||
|
'palette.primary.main',
|
||||||
|
'palette.primary.light',
|
||||||
|
'palette.primary.dark',
|
||||||
|
'logo.svgData',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user