Skip to content

Commit

Permalink
feat(frontend): implement backup dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
SARDONYX-sard committed Feb 15, 2024
1 parent 1a42f9d commit 58b69fe
Show file tree
Hide file tree
Showing 17 changed files with 524 additions and 166 deletions.
105 changes: 75 additions & 30 deletions frontend/src/components/buttons/backup_btn.tsx
Original file line number Diff line number Diff line change
@@ -1,65 +1,105 @@
import FileDownloadIcon from '@mui/icons-material/FileDownload';
import FileOpen from '@mui/icons-material/FileOpen';
import { Button, type ButtonProps, Tooltip } from '@mui/material';
import { type ReactNode } from 'react';
import { Button, Tooltip } from '@mui/material';
import { type ReactNode, useState } from 'react';

import { notify } from '@/components/notifications';
import {
LocalStorageDialog,
notify,
type DialogClickHandler,
type LocalStorageDialogProps,
} from '@/components/notifications';
import { useTranslation } from '@/hooks';
import { backup } from '@/tauri_cmd';
import { type LocalCache, localStorageManager } from '@/utils/local_storage_manager';

type Props = {
buttonName: ReactNode;
buttonName: string;
/** Trigger to open dialog */
onClick?: () => void;
startIcon: ReactNode;
tooltipTitle: ReactNode;
} & ButtonProps;
} & LocalStorageDialogProps;

export const BackupButton = ({ buttonName, tooltipTitle, ...props }: Readonly<Props>) => (
<Tooltip title={tooltipTitle}>
<Button
sx={{
height: '4em',
marginBottom: '8px',
marginRight: '8px',
marginTop: '8px',
minWidth: '120px',
width: '120px',
}}
type="button"
variant="outlined"
{...props}
>
{buttonName}
</Button>
</Tooltip>
);
export const BackupButton = ({ buttonName, startIcon, tooltipTitle, onClick, ...props }: Readonly<Props>) => {
return (
<>
<Tooltip title={tooltipTitle}>
<Button
sx={{
height: '4em',
marginBottom: '8px',
marginRight: '8px',
marginTop: '8px',
minWidth: '120px',
width: '120px',
}}
type="button"
variant="outlined"
onClick={onClick}
startIcon={startIcon}
>
{buttonName}
</Button>
</Tooltip>
<LocalStorageDialog buttonName={buttonName} {...props} />
</>
);
};

export const ImportBackupButton = () => {
const { t } = useTranslation();
const [settings, setSettings] = useState<LocalCache>({});
const [open, setOpen] = useState(false);

const handleClick = async () => {
const newSettings = await backup.import();
try {
await backup.import();
if (newSettings) {
setSettings(newSettings);
setOpen(true);
}
} catch (e) {
notify.error(`${e}`);
}
};

const handleDialogClick: DialogClickHandler = (checkedKeys) => {
checkedKeys.forEach((key) => {
const value = settings[key];
if (value) {
localStorage.setItem(key, value);
}
});

window.location.reload(); // To enable
};

return (
<BackupButton
buttonName={t('backup-import-btn-name')}
tooltipTitle={t('backup-import-tooltip')}
cacheItems={settings}
inDialogClick={handleDialogClick}
onClick={handleClick}
open={open}
setOpen={setOpen}
startIcon={<FileOpen />}
title={t('backup-import-dialog-title')}
tooltipTitle={t('backup-import-tooltip')}
/>
);
};

export const ExportBackupButton = () => {
const { t } = useTranslation();
const [open, setOpen] = useState(false);

const handleClick = async () => {
const handleClick: DialogClickHandler = async (checkedKeys) => {
try {
if (await backup.export()) {
const exportTarget = localStorageManager.getFromKeys(checkedKeys);
if (await backup.export(exportTarget)) {
notify.success(t('backup-export-success'));
setOpen(false);
}
} catch (e) {
notify.error(`${e}`);
Expand All @@ -69,9 +109,14 @@ export const ExportBackupButton = () => {
return (
<BackupButton
buttonName={t('backup-export-btn-name')}
tooltipTitle={t('backup-export-tooltip')}
onClick={handleClick}
cacheItems={localStorageManager.getAll()}
inDialogClick={handleClick}
open={open}
onClick={() => setOpen(true)}
setOpen={setOpen}
startIcon={<FileDownloadIcon />}
title={t('backup-export-dialog-title')}
tooltipTitle={t('backup-export-tooltip')}
/>
);
};
48 changes: 48 additions & 0 deletions frontend/src/components/editor/css_editor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import InputLabel from '@mui/material/InputLabel';
import AceEditor from 'react-ace';

import { useTranslation } from '@/hooks';
import { selectEditorMode } from '@/utils/selector';

export type CSSEditorProps = {
editorMode: string;
setPreset: (script: string) => void;
setStyle: (style: string) => void;
style: string;
};

export const CSSEditor = ({ editorMode, setPreset, setStyle, style }: CSSEditorProps) => {
const { t } = useTranslation();

return (
<>
<InputLabel sx={{ marginTop: '20px' }}>{t('custom-css-label')}</InputLabel>
<AceEditor
style={{
width: '95%',
backgroundColor: '#2424248c',
}}
onChange={(value) => {
setStyle(value);
localStorage.setItem('customCSS', value);
setPreset('0');
}}
fontSize={'1rem'}
height="300px"
mode="css"
theme="one_dark"
value={style}
setOptions={{ useWorker: false }}
placeholder="{ body: url('https://localhost' }"
name="Custom CSS"
enableBasicAutocompletion
enableLiveAutocompletion
enableSnippets
keyboardHandler={selectEditorMode(editorMode)}
highlightActiveLine
tabSize={2}
editorProps={{ $blockScrolling: true }}
/>
</>
);
};
12 changes: 12 additions & 0 deletions frontend/src/components/editor/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// @index('./*', f => `export * from '${f.path}'`)
export * from './css_editor';
export * from './js_editor';

// NOTE: These extensions must be loaded after importing AceEditor or they will error
import 'ace-builds/src-min-noconflict/ext-language_tools'; // For completion
import 'ace-builds/src-min-noconflict/keybinding-vim';
import 'ace-builds/src-min-noconflict/mode-css';
import 'ace-builds/src-min-noconflict/mode-javascript';
import 'ace-builds/src-min-noconflict/snippets/css';
import 'ace-builds/src-min-noconflict/snippets/javascript';
import 'ace-builds/src-min-noconflict/theme-one_dark';
76 changes: 76 additions & 0 deletions frontend/src/components/editor/js_editor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { Checkbox, FormControlLabel, Grid, Tooltip } from '@mui/material';
import InputLabel from '@mui/material/InputLabel';
import AceEditor from 'react-ace';

import { useInjectScript, useStorageState, useTranslation } from '@/hooks';
import { selectEditorMode } from '@/utils/selector';

export type JSEditorProps = {
editorMode: string;
marginTop?: string;
};
export const JSEditor = ({ editorMode, marginTop }: JSEditorProps) => {
const { t } = useTranslation();

const [script, setScript] = useInjectScript();
const [runScript, setRunScript] = useStorageState('runScript', 'false');

return (
<>
<Grid container sx={{ display: 'flex', justifyContent: 'space-evenly', width: '100%', marginTop: marginTop }}>
<InputLabel sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }} error>
{t('custom-js-label')}
</InputLabel>
<Tooltip
title={
<>
{t('custom-js-auto-run-tooltip')}
<br />
{t('custom-js-auto-run-tooltip2')}
</>
}
>
<FormControlLabel
control={
<Checkbox
checked={runScript === 'true'}
onClick={() => setRunScript(runScript === 'true' ? 'false' : 'true')}
/>
}
label={t('custom-js-auto-run-label')}
/>
</Tooltip>
</Grid>

<AceEditor
style={{
width: '95%',
backgroundColor: '#2424248c',
}}
onChange={(value) => {
localStorage.setItem('customJS', value);
setScript(value);
}}
placeholder={`(()=> {
const p = document.createElement('p');
p.innerText = 'Hello';
document.body.appendChild(p);
)()`}
editorProps={{ $blockScrolling: true }}
enableBasicAutocompletion
enableLiveAutocompletion
enableSnippets
fontSize={'1rem'}
height="250px"
highlightActiveLine
keyboardHandler={selectEditorMode(editorMode)}
mode="javascript"
name="Custom JavaScript"
setOptions={{ useWorker: false }}
tabSize={2}
theme="one_dark"
value={script}
/>
</>
);
};
2 changes: 1 addition & 1 deletion frontend/src/components/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const getInitialFormValues = (): FormProps => ({
mappingPath: localStorage.getItem('mappingPath') ?? '',
mapping1personPath: localStorage.getItem('mapping1personPath') ?? '',
loading: false as boolean,
logLevel: selectLogLevel(localStorage.getItem('logLevel') ?? 'error'),
logLevel: selectLogLevel(localStorage.getItem('logLevel')),
runParallel: localStorage.getItem('runParallel') === 'true',
hideDar: localStorage.getItem('hideDar') === 'true',
showProgress: localStorage.getItem('showProgress') === 'true',
Expand Down
Loading

0 comments on commit 58b69fe

Please sign in to comment.