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

Fix/adjustments after testing #14

Merged
merged 11 commits into from
Mar 31, 2023
4 changes: 2 additions & 2 deletions .babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
],
"plugins": [
["prismjs", {
"languages": ["json", "markup", "markup-templating", "handlebars"],
"plugins": ["line-numbers"],
"languages": ["json", "markup", "markup-templating", "handlebars", "diff"],
"plugins": ["line-numbers", "diff"],
"css": true
}]
]
Expand Down
24 changes: 20 additions & 4 deletions src/components/App/AppRoutes/AppRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,28 @@ export const AppRoutes = () => {
keycloak.onTokenExpired = undefined;
}
keycloak.onTokenExpired = () => {
keycloak.updateToken(5);
keycloak
.updateToken(5)
.then(refreshed => {
if (refreshed) {
ApiClient.setup(keycloak.token);
}
})
.catch(() => {
ApiClient.setup(keycloak.token);
});
};
// Force refresh token
keycloak.updateToken(-1);
ApiClient.setup(keycloak.token);
setHasMounted(true);
keycloak
.updateToken(-1)
.then(refreshed => {
ApiClient.setup(keycloak.token);
setHasMounted(true);
})
.catch(() => {
ApiClient.setup(keycloak.token);
setHasMounted(true);
});
return () => {
if (keycloak) keycloak.onTokenExpired = undefined;
};
Expand Down
14 changes: 12 additions & 2 deletions src/components/CodeViewer/CodeViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,35 @@ import 'prismjs/components/prism-json';
import 'prismjs/components/prism-markup';
import 'prismjs/components/prism-markup-templating';
import 'prismjs/components/prism-handlebars';
import 'prismjs/components/prism-diff';
import 'prismjs/themes/prism.css';
import 'prismjs/plugins/line-numbers/prism-line-numbers';
import 'prismjs/plugins/line-numbers/prism-line-numbers.css';
import 'prismjs/plugins/diff-highlight/prism-diff-highlight';
import 'prismjs/plugins/diff-highlight/prism-diff-highlight.css';

interface Props {
code: string;
language: string;
lineNumbers?: boolean;
diff?: boolean;
}

const CodeViewer = ({ code, language, lineNumbers = true }: Props) => {
const CodeViewer = ({ code, language, lineNumbers = true, diff = false }: Props) => {
language = language === 'plain' ? 'json' : language;
useEffect(() => {
Prism.highlightAll();
}, [code]);
return (
<Box className="CodeViewer" sx={{ width: '100%', display: 'flex' }}>
<pre className={`${lineNumbers ? 'line-numbers' : ''} w-full flex-1`} style={{ margin: 0 }}>
<code className={`language-${language}`}>{code}</code>
<code
className={`${
diff ? `language-diff-${language} diff-highlight` : `language-${language}`
}`}
>
{code}
</code>
</pre>
</Box>
);
Expand Down
63 changes: 53 additions & 10 deletions src/components/Menu/Items/OperationScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export const OperationScreen = ({

const [updateMenu] = useMutation(MenuService.UPDATE_MENU);

const handleUpdate = () => {
const handleUpdate = async (): Promise<void> => {
const formatNodes = (nodes: INode[]) =>
nodes
.map(node => {
Expand Down Expand Up @@ -179,7 +179,7 @@ export const OperationScreen = ({
};
});

updateMenu({
await updateMenu({
variables: { menu: { id: Number(id), items } },
onCompleted: data => {
dispatch({
Expand All @@ -189,17 +189,29 @@ export const OperationScreen = ({
context: 'male',
})}!`,
});
switch (editingNode.action) {
case EnumInputAction.CREATE:
case EnumInputAction.DELETE:
setSelected('');
break;
case EnumInputAction.UPDATE:
setSelected(editingNode.id.toString());
break;
}
setUpdatedMenu(data.updateMenu);
setOperationScreen(EnumInputActionScreen.SELECTING_ACTION);
setEditingNode(emptyEditingNode);
return Promise.resolve();
},
onError: error => {
openDefaultErrorNotification(error, dispatch);
return Promise.reject();
},
});
return Promise.resolve();
};

const handleInsertSubmit = (e: React.FormEvent) => {
const handleInsertSubmit = async (e: React.FormEvent) => {
e.preventDefault();
e.stopPropagation();

Expand All @@ -220,7 +232,11 @@ export const OperationScreen = ({
return;
}

handleUpdate();
try {
await handleUpdate();
} catch (error) {
console.error(error);
}
};

const handleUpdateSubmit = async (e: React.FormEvent) => {
Expand All @@ -243,7 +259,22 @@ export const OperationScreen = ({
setLabelError(tmpLabelError);
}

handleUpdate();
try {
await handleUpdate();
} catch (error) {
console.error(error);
}
};

const handleDeleteSubmit = async (e: React.FormEvent) => {
e.preventDefault();
e.stopPropagation();

try {
await handleUpdate();
} catch (error) {
console.error(error);
}
};

const handleActionChange = React.useCallback(
Expand Down Expand Up @@ -478,6 +509,17 @@ export const OperationScreen = ({
>
{t('menu.preview.actions.title')}
</Typography>
{!selected && (
<Typography
variant="subtitle1"
sx={{
color: 'error.main',
mb: '1rem',
}}
>
{t('menu.preview.errors.noItemSelected')}
</Typography>
)}
<Box
sx={{
my: '2rem',
Expand All @@ -491,6 +533,7 @@ export const OperationScreen = ({
sx={{ color: 'green' }}
variant="outlined"
color="success"
disabled={!selected}
onClick={() => handleActionChange(EnumInputActionScreen.INSERT)}
>
<AddIcon />
Expand All @@ -501,7 +544,7 @@ export const OperationScreen = ({
fontSize: '0.75rem',
lineHeight: '0.75rem',
letterSpacing: '0.18px',
color: 'green',
color: selected ? 'green' : 'grey',
ml: '0.5rem',
}}
>
Expand All @@ -523,7 +566,7 @@ export const OperationScreen = ({
fontSize: '0.75rem',
lineHeight: '0.75rem',
letterSpacing: '0.18px',
color: selected ? 'orange' : 'grey',
color: selected && selected !== '0' ? 'orange' : 'grey',
ml: '0.5rem',
}}
>
Expand All @@ -545,7 +588,7 @@ export const OperationScreen = ({
fontSize: '0.75rem',
lineHeight: '0.75rem',
letterSpacing: '0.18px',
color: selected ? 'red' : 'grey',
color: selected && selected !== '0' ? 'red' : 'grey',
ml: '0.5rem',
}}
>
Expand All @@ -567,7 +610,7 @@ export const OperationScreen = ({
fontSize: '0.75rem',
lineHeight: '0.75rem',
letterSpacing: '0.18px',
color: 'black',
color: selected && selected !== '0' ? 'black' : 'grey',
ml: '0.5rem',
}}
>
Expand Down Expand Up @@ -1237,7 +1280,7 @@ export const OperationScreen = ({
variant="contained"
color="success"
sx={{ mt: '2rem', mr: '1rem' }}
onClick={handleUpdate}
onClick={handleDeleteSubmit}
>
{t('buttons.save')}
</Button>
Expand Down
27 changes: 25 additions & 2 deletions src/components/Menu/Pendencies/PendencyTableRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,21 @@ import ThumbDownOffAltIcon from '@mui/icons-material/ThumbDownOffAlt';
import { EnumInputAction, IMenu, IMenuPendency } from '../../../types';
import CodeViewer from '../../CodeViewer';
import { IUpdateMenuItemInput, IUpdateMenuMetaInput } from '../../../types/input';
import { codeDiff } from '../../../utils/diff/codeDiff';

const PendencyChanges = ({ menu, pendency }: { menu: IMenu; pendency: IMenuPendency }) => {
const { i18n, t } = useTranslation();

const templateDiff = React.useMemo(() => {
if (pendency.input.template) {
const oldTemplate =
menu.template ||
menu.defaultTemplate?.[pendency.input.templateFormat || menu.templateFormat];
return codeDiff(oldTemplate, pendency.input.template);
}
return '';
}, [menu, pendency]);

const getActionColor = (action: EnumInputAction) => {
switch (action) {
case EnumInputAction.CREATE:
Expand Down Expand Up @@ -43,6 +54,18 @@ const PendencyChanges = ({ menu, pendency }: { menu: IMenu; pendency: IMenuPende
const order = item.order || menu.items.find(i => i.id === item.id)?.order || index + 1;
const label = menu.items.find(i => i.id === item.id)?.label || item.label;
const actionColor = getActionColor(item.action);
let templateDiff = '';
if (item.template) {
const oldItem = menu.items.find(i => i.id === item.id);
const oldTemplate =
oldItem.template ||
oldItem.defaultTemplate[
item.templateFormat || oldItem.templateFormat || menu.templateFormat
];
if (oldTemplate) {
templateDiff = codeDiff(oldTemplate, item.template);
}
}
return (
<Box className="flex flex-col">
<Box className="flex flex-row items-center min-w-fit">
Expand Down Expand Up @@ -101,7 +124,7 @@ const PendencyChanges = ({ menu, pendency }: { menu: IMenu; pendency: IMenuPende
<Typography>
<b>{t('menuItem.fields.template')}</b>:
</Typography>
<CodeViewer code={item.template} language="handlebars" />
<CodeViewer code={templateDiff} language="handlebars" diff />
</Box>
)}
{item.meta && Object.keys(item.meta).length > 0 && (
Expand Down Expand Up @@ -215,7 +238,7 @@ const PendencyChanges = ({ menu, pendency }: { menu: IMenu; pendency: IMenuPende
<Typography>
<b>{t('menu.fields.template')}</b>:
</Typography>
<CodeViewer code={pendency.input.template} language="handlebars" />
<CodeViewer code={templateDiff} language="handlebars" diff />
</Box>
)}
{pendency.input.meta && pendency.input.meta.length > 0 && (
Expand Down
65 changes: 55 additions & 10 deletions src/components/Menu/Revisions/Diff.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,58 @@
import React from 'react';
import { Box, Typography } from '@mui/material';
import { Box, styled, Typography } from '@mui/material';
import MuiAccordion, { AccordionProps } from '@mui/material/Accordion';
import MuiAccordionSummary, { AccordionSummaryProps } from '@mui/material/AccordionSummary';
import MuiAccordionDetails from '@mui/material/AccordionDetails';
import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
import { Link } from 'react-router-dom';
import ArrowForwardIosSharpIcon from '@mui/icons-material/ArrowForwardIosSharp';
import { useTranslation } from 'react-i18next';
import { codeDiff } from '../../../utils/diff/codeDiff';
import CodeViewer from '../../CodeViewer';

interface Props {
id: string;
diff: any;
snapshot: any;
renderTemplateChanges?: (from: any, to: any, linkPath: string) => JSX.Element;
}

export const MenuRevisionsDiff = ({ id, diff, snapshot, renderTemplateChanges }: Props) => {
const Accordion = styled((props: AccordionProps) => (
<MuiAccordion disableGutters elevation={0} square {...props} />
))(({ theme }) => ({
border: `1px solid ${theme.palette.divider}`,
'&:not(:last-child)': {
borderBottom: 0,
},
'&:before': {
display: 'none',
},
}));

const AccordionSummary = styled((props: AccordionSummaryProps) => (
<MuiAccordionSummary
expandIcon={<ArrowForwardIosSharpIcon sx={{ fontSize: '0.9rem' }} />}
{...props}
/>
))(({ theme }) => ({
backgroundColor:
theme.palette.mode === 'dark' ? 'rgba(255, 255, 255, .05)' : 'rgba(0, 0, 0, .03)',
flexDirection: 'row-reverse',
'& .MuiAccordionSummary-expandIconWrapper.Mui-expanded': {
transform: 'rotate(90deg)',
},
'& .MuiAccordionSummary-content': {
marginLeft: theme.spacing(1),
},
}));

const AccordionDetails = styled(MuiAccordionDetails)(({ theme }) => ({
padding: theme.spacing(2),
borderTop: '1px solid rgba(0, 0, 0, .125)',
}));

export const MenuRevisionsDiff = ({ id, diff, snapshot }: Props) => {
const { t } = useTranslation();

const defaultRenderTemplateChanges = (from: any, to: any, linkPath: string) => {
const renderTemplateChanges = (from: any, to: any, linkPath: string) => {
if (to === undefined || (from === undefined && to === null))
return (
<Typography variant="body1" component="p">
Expand All @@ -33,15 +71,22 @@ export const MenuRevisionsDiff = ({ id, diff, snapshot, renderTemplateChanges }:
{t('common.changed', { context: 'male' })}
</Typography>
);
const fromTemplate = from || '';
const templateDiff = codeDiff(fromTemplate, to);
return (
<Typography variant="body1" component="span" sx={{ textDecorationLine: 'underline' }}>
<Link to={linkPath}>{t('common.viewChanges')}</Link>
</Typography>
<Box className="mt-2">
<Accordion>
<AccordionSummary aria-controls="panel1a-content" id="panel1a-header">
{t('common.viewChanges')}
</AccordionSummary>
<AccordionDetails>
<CodeViewer code={templateDiff} language="handlebars" diff />
</AccordionDetails>
</Accordion>
</Box>
);
};

renderTemplateChanges = renderTemplateChanges || defaultRenderTemplateChanges;

const renderChanges = (from?: any, to?: any) => {
if (to === undefined || (from === undefined && to === null) || from === to)
return (
Expand Down
Loading