feat(user-interface): use default config as fallback (#1251)

* feat(user-interface): return default app values

* test: remove skip in UI tests

---------

Co-authored-by: Ali BARIN <ali.barin53@gmail.com>
This commit is contained in:
Rıdvan Akca
2023-09-11 15:06:05 +03:00
committed by GitHub
parent 5271033d34
commit 25ce63b86d
4 changed files with 101 additions and 71 deletions

View File

@@ -1,7 +1,7 @@
// @ts-check // @ts-check
const { test, expect } = require('../../fixtures/index'); const { test, expect } = require('../../fixtures/index');
test.describe.skip('User interface page', () => { test.describe('User interface page', () => {
test.beforeEach(async ({ userInterfacePage }) => { test.beforeEach(async ({ userInterfacePage }) => {
await userInterfacePage.profileMenuButton.click(); await userInterfacePage.profileMenuButton.click();
await userInterfacePage.adminMenuItem.click(); await userInterfacePage.adminMenuItem.click();
@@ -43,16 +43,6 @@ test.describe.skip('User interface page', () => {
initialRgbColor initialRgbColor
); );
}); });
test('checks custom logo', async ({ userInterfacePage }) => {
const initialLogoSvgCode =
await userInterfacePage.logoSvgCodeInput.inputValue();
const logoSrcAttribute = await userInterfacePage.customLogo.getAttribute(
'src'
);
const svgCode = userInterfacePage.encodeSVG(initialLogoSvgCode);
expect(logoSrcAttribute).toMatch(svgCode);
});
}); });
test.describe( test.describe(
@@ -90,44 +80,6 @@ test.describe.skip('User interface page', () => {
} }
); );
test.describe(
'update form based on input values and check if the inputs still reflect them',
async () => {
test('update primary main color and check color input', async ({
userInterfacePage,
}) => {
await userInterfacePage.primaryMainColorInput.fill('#00adef');
await userInterfacePage.updateButton.click();
const rgbColor = userInterfacePage.hexToRgb('#00adef');
const button = await userInterfacePage.primaryMainColorButton;
const styleAttribute = await button.getAttribute('style');
expect(styleAttribute).toBe(`background-color: ${rgbColor};`);
});
test('update primary dark color and check color input', async ({
userInterfacePage,
}) => {
await userInterfacePage.primaryDarkColorInput.fill('#222222');
await userInterfacePage.updateButton.click();
const rgbColor = userInterfacePage.hexToRgb('#222222');
const button = await userInterfacePage.primaryDarkColorButton;
const styleAttribute = await button.getAttribute('style');
expect(styleAttribute).toBe(`background-color: ${rgbColor};`);
});
test('update primary light color and check color input', async ({
userInterfacePage,
}) => {
await userInterfacePage.primaryLightColorInput.fill('#f90707');
await userInterfacePage.updateButton.click();
const rgbColor = userInterfacePage.hexToRgb('#f90707');
const button = await userInterfacePage.primaryLightColorButton;
const styleAttribute = await button.getAttribute('style');
expect(styleAttribute).toBe(`background-color: ${rgbColor};`);
});
}
);
test.describe('update form based on input values', async () => { test.describe('update form based on input values', async () => {
test('fill primary main color', async ({ userInterfacePage }) => { test('fill primary main color', async ({ userInterfacePage }) => {
await userInterfacePage.primaryMainColorInput.fill('#00adef'); await userInterfacePage.primaryMainColorInput.fill('#00adef');
@@ -147,14 +99,15 @@ test.describe.skip('User interface page', () => {
}); });
}); });
test('fill primary light color', async ({ userInterfacePage }) => { test.skip('fill primary light color', async ({ userInterfacePage }) => {
await userInterfacePage.primaryLightColorInput.fill('#f90707'); await userInterfacePage.primaryLightColorInput.fill('#f90707');
await userInterfacePage.updateButton.click(); await userInterfacePage.updateButton.click();
await userInterfacePage.goToDashboardButton.click(); await userInterfacePage.goToDashboardButton.click();
await expect(userInterfacePage.page).toHaveURL('/flows'); await expect(userInterfacePage.page).toHaveURL('/flows');
const span = await userInterfacePage.flowRowCardActionArea; await userInterfacePage.flowRowCardActionArea.waitFor({
await span.waitFor({ state: 'visible' }); state: 'visible',
await span.hover(); });
await userInterfacePage.flowRowCardActionArea.hover();
await userInterfacePage.screenshot({ await userInterfacePage.screenshot({
path: 'updated primary light color.png', path: 'updated primary light color.png',
}); });
@@ -173,4 +126,45 @@ test.describe.skip('User interface page', () => {
}); });
}); });
}); });
test.describe(
'update form based on input values and check if the inputs still reflect them',
async () => {
test('update primary main color and check color input', async ({
userInterfacePage,
}) => {
await userInterfacePage.primaryMainColorInput.fill('#00adef');
await userInterfacePage.updateButton.click();
await userInterfacePage.snackbar.waitFor({ state: 'visible' });
const rgbColor = userInterfacePage.hexToRgb('#00adef');
const button = await userInterfacePage.primaryMainColorButton;
const styleAttribute = await button.getAttribute('style');
expect(styleAttribute).toEqual(`background-color: ${rgbColor};`);
});
test('update primary dark color and check color input', async ({
userInterfacePage,
}) => {
await userInterfacePage.primaryDarkColorInput.fill('#222222');
await userInterfacePage.updateButton.click();
await userInterfacePage.snackbar.waitFor({ state: 'visible' });
const rgbColor = userInterfacePage.hexToRgb('#222222');
const button = await userInterfacePage.primaryDarkColorButton;
const styleAttribute = await button.getAttribute('style');
expect(styleAttribute).toEqual(`background-color: ${rgbColor};`);
});
test('update primary light color and check color input', async ({
userInterfacePage,
}) => {
await userInterfacePage.primaryLightColorInput.fill('#f90707');
await userInterfacePage.updateButton.click();
await userInterfacePage.snackbar.waitFor({ state: 'visible' });
const rgbColor = userInterfacePage.hexToRgb('#f90707');
const button = await userInterfacePage.primaryLightColorButton;
const styleAttribute = await button.getAttribute('style');
expect(styleAttribute).toEqual(`background-color: ${rgbColor};`);
});
}
);
}); });

View File

@@ -220,11 +220,11 @@
"appAuthClientsDialog.title": "Choose your authentication client", "appAuthClientsDialog.title": "Choose your authentication client",
"userInterfacePage.title": "User Interface", "userInterfacePage.title": "User Interface",
"userInterfacePage.successfullyUpdated": "User interface has been updated.", "userInterfacePage.successfullyUpdated": "User interface has been updated.",
"userInterfacePage.metadataTitle": "Title", "userInterfacePage.titleFieldLabel": "Title",
"userInterfacePage.mainColor": "Primary main color", "userInterfacePage.primaryMainColorFieldLabel": "Primary main color",
"userInterfacePage.darkColor": "Primary dark color", "userInterfacePage.primaryDarkColorFieldLabel": "Primary dark color",
"userInterfacePage.lightColor": "Primary light color", "userInterfacePage.primaryLightColorFieldLabel": "Primary light color",
"userInterfacePage.svgData": "Logo SVG code", "userInterfacePage.svgDataFieldLabel": "Logo SVG code",
"userInterfacePage.submit": "Update", "userInterfacePage.submit": "Update",
"authenticationPage.title": "Single Sign-On with SAML", "authenticationPage.title": "Single Sign-On with SAML",
"authenticationForm.active": "Active", "authenticationForm.active": "Active",

View File

@@ -2,8 +2,10 @@ import * as React from 'react';
import { useMutation } from '@apollo/client'; import { useMutation } from '@apollo/client';
import Grid from '@mui/material/Grid'; import Grid from '@mui/material/Grid';
import Stack from '@mui/material/Stack'; import Stack from '@mui/material/Stack';
import Skeleton from '@mui/material/Skeleton';
import LoadingButton from '@mui/lab/LoadingButton'; import LoadingButton from '@mui/lab/LoadingButton';
import { useSnackbar } from 'notistack'; import { useSnackbar } from 'notistack';
import merge from 'lodash/merge';
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';
@@ -14,7 +16,11 @@ import TextField from 'components/TextField';
import useFormatMessage from 'hooks/useFormatMessage'; import useFormatMessage from 'hooks/useFormatMessage';
import ColorInput from 'components/ColorInput'; import ColorInput from 'components/ColorInput';
import nestObject from 'helpers/nestObject'; import nestObject from 'helpers/nestObject';
import { Skeleton } from '@mui/material'; import {
primaryMainColor,
primaryDarkColor,
primaryLightColor,
} from 'styles/theme';
type UserInterface = { type UserInterface = {
palette: { palette: {
@@ -30,6 +36,17 @@ type UserInterface = {
}; };
}; };
const getPrimaryMainColor = (color?: string) => color || primaryMainColor;
const getPrimaryDarkColor = (color?: string) => color || primaryDarkColor;
const getPrimaryLightColor = (color?: string) => color || primaryLightColor;
const defaultValues = {
title: 'Automatisch',
'palette.primary.main': primaryMainColor,
'palette.primary.dark': primaryDarkColor,
'palette.primary.light': primaryLightColor,
};
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, {
@@ -43,6 +60,10 @@ export default function UserInterface(): React.ReactElement {
'logo.svgData', 'logo.svgData',
]); ]);
const { enqueueSnackbar } = useSnackbar(); const { enqueueSnackbar } = useSnackbar();
const configWithDefaults = merge(
defaultValues,
nestObject<UserInterface>(config)
);
const handleUserInterfaceUpdate = async (uiData: Partial<UserInterface>) => { const handleUserInterfaceUpdate = async (uiData: Partial<UserInterface>) => {
try { try {
@@ -50,9 +71,15 @@ export default function UserInterface(): React.ReactElement {
variables: { variables: {
input: { input: {
title: uiData?.title, title: uiData?.title,
'palette.primary.main': uiData?.palette?.primary.main, 'palette.primary.main': getPrimaryMainColor(
'palette.primary.dark': uiData?.palette?.primary.dark, uiData?.palette?.primary.main
'palette.primary.light': uiData?.palette?.primary.light, ),
'palette.primary.dark': getPrimaryDarkColor(
uiData?.palette?.primary.dark
),
'palette.primary.light': getPrimaryLightColor(
uiData?.palette?.primary.light
),
'logo.svgData': uiData?.logo?.svgData, 'logo.svgData': uiData?.logo?.svgData,
}, },
}, },
@@ -86,39 +113,45 @@ export default function UserInterface(): React.ReactElement {
{!configLoading && ( {!configLoading && (
<Form <Form
onSubmit={handleUserInterfaceUpdate} onSubmit={handleUserInterfaceUpdate}
defaultValues={nestObject<UserInterface>(config)} defaultValues={configWithDefaults}
> >
<Stack direction="column" gap={2}> <Stack direction="column" gap={2}>
<TextField <TextField
name="title" name="title"
label={formatMessage('userInterfacePage.metadataTitle')} label={formatMessage('userInterfacePage.titleFieldLabel')}
fullWidth fullWidth
/> />
<ColorInput <ColorInput
name="palette.primary.main" name="palette.primary.main"
label={formatMessage('userInterfacePage.mainColor')} label={formatMessage(
'userInterfacePage.primaryMainColorFieldLabel'
)}
fullWidth fullWidth
data-test="primary-main-color-input" data-test="primary-main-color-input"
/> />
<ColorInput <ColorInput
name="palette.primary.dark" name="palette.primary.dark"
label={formatMessage('userInterfacePage.darkColor')} label={formatMessage(
'userInterfacePage.primaryDarkColorFieldLabel'
)}
fullWidth fullWidth
data-test="primary-dark-color-input" data-test="primary-dark-color-input"
/> />
<ColorInput <ColorInput
name="palette.primary.light" name="palette.primary.light"
label={formatMessage('userInterfacePage.lightColor')} label={formatMessage(
'userInterfacePage.primaryLightColorFieldLabel'
)}
fullWidth fullWidth
data-test="primary-light-color-input" data-test="primary-light-color-input"
/> />
<TextField <TextField
name="logo.svgData" name="logo.svgData"
label={formatMessage('userInterfacePage.svgData')} label={formatMessage('userInterfacePage.svgDataFieldLabel')}
multiline multiline
fullWidth fullWidth
data-test="logo-svg-data-text-field" data-test="logo-svg-data-text-field"

View File

@@ -2,13 +2,16 @@ import { createTheme, alpha } from '@mui/material/styles';
import { cardActionAreaClasses } from '@mui/material/CardActionArea'; import { cardActionAreaClasses } from '@mui/material/CardActionArea';
const referenceTheme = createTheme(); const referenceTheme = createTheme();
export const primaryMainColor = '#0059F7';
export const primaryLightColor = '#4286FF';
export const primaryDarkColor = '#001F52';
const extendedTheme = createTheme({ const extendedTheme = createTheme({
palette: { palette: {
primary: { primary: {
main: '#0059F7', main: primaryMainColor,
light: '#4286FF', light: primaryLightColor,
dark: '#001F52', dark: primaryDarkColor,
contrastText: '#fff', contrastText: '#fff',
}, },
divider: 'rgba(194, 194, 194, .2)', divider: 'rgba(194, 194, 194, .2)',