Handle missing trackers in backup validation result

This commit is contained in:
schroda
2024-05-01 16:56:18 +02:00
parent 4f92a0130e
commit 86ec83a2ef
6 changed files with 97 additions and 38 deletions

View File

@@ -826,7 +826,8 @@
"dialog": { "dialog": {
"content": { "content": {
"label": { "label": {
"missing_sources": "The following sources are not installed:" "missing_sources": "The following sources are not installed:",
"missing_trackers": "The following trackers are not logged in:"
} }
}, },
"title": "Backup validation" "title": "Backup validation"

View File

@@ -1020,15 +1020,20 @@ export type UpdateTrackPayloadFieldPolicy = {
clientMutationId?: FieldPolicy<any> | FieldReadFunction<any>, clientMutationId?: FieldPolicy<any> | FieldReadFunction<any>,
trackRecord?: FieldPolicy<any> | FieldReadFunction<any> trackRecord?: FieldPolicy<any> | FieldReadFunction<any>
}; };
export type ValidateBackupResultKeySpecifier = ('missingSources' | ValidateBackupResultKeySpecifier)[]; export type ValidateBackupResultKeySpecifier = ('missingSources' | 'missingTrackers' | ValidateBackupResultKeySpecifier)[];
export type ValidateBackupResultFieldPolicy = { export type ValidateBackupResultFieldPolicy = {
missingSources?: FieldPolicy<any> | FieldReadFunction<any> missingSources?: FieldPolicy<any> | FieldReadFunction<any>,
missingTrackers?: FieldPolicy<any> | FieldReadFunction<any>
}; };
export type ValidateBackupSourceKeySpecifier = ('id' | 'name' | ValidateBackupSourceKeySpecifier)[]; export type ValidateBackupSourceKeySpecifier = ('id' | 'name' | ValidateBackupSourceKeySpecifier)[];
export type ValidateBackupSourceFieldPolicy = { export type ValidateBackupSourceFieldPolicy = {
id?: FieldPolicy<any> | FieldReadFunction<any>, id?: FieldPolicy<any> | FieldReadFunction<any>,
name?: FieldPolicy<any> | FieldReadFunction<any> name?: FieldPolicy<any> | FieldReadFunction<any>
}; };
export type ValidateBackupTrackerKeySpecifier = ('name' | ValidateBackupTrackerKeySpecifier)[];
export type ValidateBackupTrackerFieldPolicy = {
name?: FieldPolicy<any> | FieldReadFunction<any>
};
export type WebUIUpdateCheckKeySpecifier = ('channel' | 'tag' | 'updateAvailable' | WebUIUpdateCheckKeySpecifier)[]; export type WebUIUpdateCheckKeySpecifier = ('channel' | 'tag' | 'updateAvailable' | WebUIUpdateCheckKeySpecifier)[];
export type WebUIUpdateCheckFieldPolicy = { export type WebUIUpdateCheckFieldPolicy = {
channel?: FieldPolicy<any> | FieldReadFunction<any>, channel?: FieldPolicy<any> | FieldReadFunction<any>,
@@ -1552,6 +1557,10 @@ export type StrictTypedTypePolicies = {
keyFields?: false | ValidateBackupSourceKeySpecifier | (() => undefined | ValidateBackupSourceKeySpecifier), keyFields?: false | ValidateBackupSourceKeySpecifier | (() => undefined | ValidateBackupSourceKeySpecifier),
fields?: ValidateBackupSourceFieldPolicy, fields?: ValidateBackupSourceFieldPolicy,
}, },
ValidateBackupTracker?: Omit<TypePolicy, "fields" | "keyFields"> & {
keyFields?: false | ValidateBackupTrackerKeySpecifier | (() => undefined | ValidateBackupTrackerKeySpecifier),
fields?: ValidateBackupTrackerFieldPolicy,
},
WebUIUpdateCheck?: Omit<TypePolicy, "fields" | "keyFields"> & { WebUIUpdateCheck?: Omit<TypePolicy, "fields" | "keyFields"> & {
keyFields?: false | WebUIUpdateCheckKeySpecifier | (() => undefined | WebUIUpdateCheckKeySpecifier), keyFields?: false | WebUIUpdateCheckKeySpecifier | (() => undefined | WebUIUpdateCheckKeySpecifier),
fields?: WebUIUpdateCheckFieldPolicy, fields?: WebUIUpdateCheckFieldPolicy,

View File

@@ -2523,6 +2523,7 @@ export type ValidateBackupInput = {
export type ValidateBackupResult = { export type ValidateBackupResult = {
__typename?: 'ValidateBackupResult'; __typename?: 'ValidateBackupResult';
missingSources: Array<ValidateBackupSource>; missingSources: Array<ValidateBackupSource>;
missingTrackers: Array<ValidateBackupTracker>;
}; };
export type ValidateBackupSource = { export type ValidateBackupSource = {
@@ -2531,6 +2532,11 @@ export type ValidateBackupSource = {
name: Scalars['String']['output']; name: Scalars['String']['output'];
}; };
export type ValidateBackupTracker = {
__typename?: 'ValidateBackupTracker';
name: Scalars['String']['output'];
};
export enum WebUiChannel { export enum WebUiChannel {
Bundled = 'BUNDLED', Bundled = 'BUNDLED',
Preview = 'PREVIEW', Preview = 'PREVIEW',
@@ -3052,7 +3058,7 @@ export type ValidateBackupQueryVariables = Exact<{
}>; }>;
export type ValidateBackupQuery = { __typename?: 'Query', validateBackup: { __typename?: 'ValidateBackupResult', missingSources: Array<{ __typename?: 'ValidateBackupSource', id: string, name: string }> } }; export type ValidateBackupQuery = { __typename?: 'Query', validateBackup: { __typename?: 'ValidateBackupResult', missingSources: Array<{ __typename?: 'ValidateBackupSource', id: string, name: string }>, missingTrackers: Array<{ __typename?: 'ValidateBackupTracker', name: string }> } };
export type GetRestoreStatusQueryVariables = Exact<{ export type GetRestoreStatusQueryVariables = Exact<{
id: Scalars['String']['input']; id: Scalars['String']['input'];

View File

@@ -15,6 +15,9 @@ export const VALIDATE_BACKUP = gql`
id id
name name
} }
missingTrackers {
name
}
} }
} }
`; `;

View File

@@ -22,6 +22,7 @@ import DialogActions from '@mui/material/DialogActions';
import Button from '@mui/material/Button'; import Button from '@mui/material/Button';
import ListItem from '@mui/material/ListItem'; import ListItem from '@mui/material/ListItem';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import Stack from '@mui/material/Stack';
import { requestManager } from '@/lib/requests/RequestManager.ts'; import { requestManager } from '@/lib/requests/RequestManager.ts';
import { makeToast } from '@/components/util/Toast'; import { makeToast } from '@/components/util/Toast';
import { NavBarContext, useSetDefaultBackTo } from '@/components/context/NavbarContext'; import { NavBarContext, useSetDefaultBackTo } from '@/components/context/NavbarContext';
@@ -84,7 +85,7 @@ export function Backup() {
const [currentBackupFile, setCurrentBackupFile] = useState<File | null>(null); const [currentBackupFile, setCurrentBackupFile] = useState<File | null>(null);
const [isInvalidBackupDialogOpen, setIsInvalidBackupDialogOpen] = useState(false); const [isInvalidBackupDialogOpen, setIsInvalidBackupDialogOpen] = useState(false);
const [missingSources, setMissingSources] = useState<ValidateBackupQuery['validateBackup']['missingSources']>([]); const [validationResult, setValidationResult] = useState<ValidateBackupQuery['validateBackup']>();
const [, setTriggerReRender] = useState(0); const [, setTriggerReRender] = useState(0);
@@ -142,8 +143,8 @@ export function Backup() {
data: { validateBackup: validateBackupData }, data: { validateBackup: validateBackupData },
} = await requestManager.validateBackupFile(file, { fetchPolicy: 'network-only' }).response; } = await requestManager.validateBackupFile(file, { fetchPolicy: 'network-only' }).response;
if (validateBackupData.missingSources.length) { if (validateBackupData.missingSources.length || validateBackupData.missingTrackers.length) {
setMissingSources([...validateBackupData.missingSources]); setValidationResult(validateBackupData);
setIsInvalidBackupDialogOpen(true); setIsInvalidBackupDialogOpen(true);
return false; return false;
} }
@@ -316,38 +317,77 @@ export function Backup() {
<Dialog open={isInvalidBackupDialogOpen}> <Dialog open={isInvalidBackupDialogOpen}>
<DialogTitle>{t('settings.backup.action.validate.dialog.title')}</DialogTitle> <DialogTitle>{t('settings.backup.action.validate.dialog.title')}</DialogTitle>
<DialogContent dividers> <DialogContent dividers>
{!!validationResult?.missingSources.length && (
<List <List
sx={{ listStyleType: 'initial', listStylePosition: 'inside' }} sx={{ listStyleType: 'initial', listStylePosition: 'inside' }}
subheader={t('settings.backup.action.validate.dialog.content.label.missing_sources')} subheader={t('settings.backup.action.validate.dialog.content.label.missing_sources')}
> >
{missingSources.map(({ id, name }) => ( {validationResult?.missingSources.map(({ id, name }) => (
<ListItem sx={{ display: 'list-item' }} key={id}> <ListItem sx={{ display: 'list-item' }} key={id}>
{`${name} (${id})`} {`${name} (${id})`}
</ListItem> </ListItem>
))} ))}
</List> </List>
)}
{!!validationResult?.missingTrackers.length && (
<List
sx={{ listStyleType: 'initial', listStylePosition: 'inside' }}
subheader={t('settings.backup.action.validate.dialog.content.label.missing_trackers')}
>
{validationResult?.missingTrackers.map(({ name }) => (
<ListItem sx={{ display: 'list-item' }} key={name}>
{`${name}`}
</ListItem>
))}
</List>
)}
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>
<Button onClick={closeInvalidBackupDialog}>{t('global.button.cancel')}</Button> <Stack sx={{ width: '100%' }} direction="row" justifyContent="space-between">
{!!validationResult?.missingSources.length && (
<Button <Button
onClick={closeInvalidBackupDialog} onClick={closeInvalidBackupDialog}
component={Link} component={Link}
to="/extensions" to="/extensions"
autoFocus={!!missingSources.length} autoFocus={!!validationResult?.missingSources.length}
variant={missingSources.length ? 'contained' : 'text'} variant={validationResult?.missingSources.length ? 'contained' : 'text'}
> >
{t('extension.action.label.install')} {t('extension.action.label.install')}
</Button> </Button>
)}
{!!validationResult?.missingTrackers.length && (
<Button
onClick={closeInvalidBackupDialog}
component={Link}
to="/settings/trackingSettings"
autoFocus={!!validationResult?.missingTrackers.length}
variant={validationResult?.missingTrackers.length ? 'contained' : 'text'}
>
{t('global.button.log_in')}
</Button>
)}
<Stack direction="row">
<Button onClick={closeInvalidBackupDialog}>{t('global.button.cancel')}</Button>
<Button <Button
onClick={() => { onClick={() => {
closeInvalidBackupDialog(); closeInvalidBackupDialog();
restoreBackup(currentBackupFile!); restoreBackup(currentBackupFile!);
}} }}
autoFocus={!missingSources.length} autoFocus={
variant={!missingSources.length ? 'contained' : 'text'} !validationResult?.missingSources.length &&
!validationResult?.missingTrackers.length
}
variant={
!validationResult?.missingSources.length &&
!validationResult?.missingTrackers.length
? 'contained'
: 'text'
}
> >
{t('global.button.restore')} {t('global.button.restore')}
</Button> </Button>
</Stack>
</Stack>
</DialogActions> </DialogActions>
</Dialog> </Dialog>
</> </>

View File

@@ -1,7 +1,7 @@
[ [
{ {
"uiVersion": "PREVIEW", "uiVersion": "PREVIEW",
"serverVersion": "r1514" "serverVersion": "r1520"
}, },
{ {
"tag": "v1.0.0", "tag": "v1.0.0",