BulkDeleteProvisionedResource: Move progress bar into a second step (#108417)
* Move progress bar into a second step --------- Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>
This commit is contained in:
co-authored by
Alex Khomenko
parent
0dbede9ba5
commit
2c86460fe3
@@ -1,5 +1,5 @@
|
||||
import { Trans } from '@grafana/i18n';
|
||||
import { Box, Text } from '@grafana/ui';
|
||||
import { Box, Icon, Text, Stack } from '@grafana/ui';
|
||||
import ProgressBar from 'app/features/provisioning/Shared/ProgressBar';
|
||||
|
||||
export interface ProgressState {
|
||||
@@ -13,16 +13,19 @@ export function BulkActionProgress({ progress }: { progress: ProgressState }) {
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Text>
|
||||
<Trans
|
||||
i18nKey="browse-dashboards.bulk-move-resources-form.progress"
|
||||
defaults="Progress: {{current}} of {{total}}"
|
||||
values={{ current: progress.current, total: progress.total }}
|
||||
/>
|
||||
</Text>
|
||||
<ProgressBar progress={progressPercentage} />
|
||||
<Stack direction="row" alignItems="center">
|
||||
<Text>
|
||||
<Trans
|
||||
i18nKey="browse-dashboards.bulk-move-resources-form.progress"
|
||||
defaults="Progress: {{current}} of {{total}}"
|
||||
values={{ current: progress.current, total: progress.total }}
|
||||
/>
|
||||
</Text>
|
||||
<Icon name="spinner" className="fa-spin" size="sm" />
|
||||
</Stack>
|
||||
<ProgressBar progress={progressPercentage} topBottomSpacing={1} />
|
||||
<Text variant="bodySmall" color="secondary">
|
||||
{progress.item}
|
||||
<Trans i18nKey="browse-dashboards.bulk-move-resources-form.deleting" defaults="Deleting:" /> {progress.item}
|
||||
</Text>
|
||||
</Box>
|
||||
);
|
||||
|
||||
+74
-42
@@ -2,10 +2,8 @@ import { useState } from 'react';
|
||||
import { FormProvider, useForm } from 'react-hook-form';
|
||||
import { useNavigate } from 'react-router-dom-v5-compat';
|
||||
|
||||
import { AppEvents } from '@grafana/data';
|
||||
import { Trans, t } from '@grafana/i18n';
|
||||
import { getAppEvents } from '@grafana/runtime';
|
||||
import { Box, Button, Stack } from '@grafana/ui';
|
||||
import { Alert, Box, Button, Stack } from '@grafana/ui';
|
||||
import {
|
||||
DeleteRepositoryFilesWithPathApiArg,
|
||||
DeleteRepositoryFilesWithPathApiResponse,
|
||||
@@ -56,6 +54,11 @@ type BulkSuccessResponse = Array<{
|
||||
data: DeleteRepositoryFilesWithPathApiResponse;
|
||||
}>;
|
||||
|
||||
type MoveResultSuccessState = {
|
||||
allSuccess: boolean;
|
||||
repoUrl?: string;
|
||||
};
|
||||
|
||||
function FormContent({
|
||||
initialValues,
|
||||
selectedItems,
|
||||
@@ -65,10 +68,17 @@ function FormContent({
|
||||
isGitHub,
|
||||
onDismiss,
|
||||
}: FormProps) {
|
||||
const [deleteRepoFile, request] = useDeleteRepositoryFilesWithPathMutation();
|
||||
// States
|
||||
const [progress, setProgress] = useState<ProgressState | null>(null);
|
||||
const [failureResults, setFailureResults] = useState<MoveResultFailed[] | undefined>();
|
||||
const [successState, setSuccessState] = useState<MoveResultSuccessState>({
|
||||
allSuccess: false,
|
||||
repoUrl: '',
|
||||
});
|
||||
const [hasSubmitted, setHasSubmitted] = useState(false);
|
||||
|
||||
// Hooks
|
||||
const [deleteRepoFile, request] = useDeleteRepositoryFilesWithPathMutation();
|
||||
const methods = useForm<BulkDeleteFormData>({ defaultValues: initialValues });
|
||||
const childrenByParentUID = useChildrenByParentUIDState();
|
||||
const rootItems = useSelector(rootItemsSelector);
|
||||
@@ -84,21 +94,11 @@ function FormContent({
|
||||
return isFolder ? `${folderPath}/${item.title}/` : fetchProvisionedDashboardPath(uid);
|
||||
};
|
||||
|
||||
const handleSuccess = (successes: BulkSuccessResponse) => {
|
||||
getAppEvents().publish({
|
||||
type: AppEvents.alertSuccess.name,
|
||||
payload: [
|
||||
t('browse-dashboards.bulk-delete-resources-form.api-success', `Successfully deleted {{count}} items`, {
|
||||
count: successes.length,
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
const handleSuccess = () => {
|
||||
if (workflow === 'branch') {
|
||||
onDismiss?.();
|
||||
const repoUrl = successes[0].data.urls?.repositoryURL;
|
||||
if (repoUrl) {
|
||||
navigate({ search: `?repo_url=${encodeURIComponent(repoUrl)}` });
|
||||
if (successState.repoUrl) {
|
||||
navigate({ search: `?repo_url=${encodeURIComponent(successState.repoUrl)}` });
|
||||
return;
|
||||
}
|
||||
window.location.reload();
|
||||
@@ -110,6 +110,7 @@ function FormContent({
|
||||
|
||||
const handleSubmitForm = async (data: BulkDeleteFormData) => {
|
||||
setFailureResults(undefined);
|
||||
setHasSubmitted(true);
|
||||
|
||||
const targets = collectSelectedItems(selectedItems, childrenByParentUID, rootItems?.items || []);
|
||||
|
||||
@@ -175,12 +176,43 @@ function FormContent({
|
||||
setProgress(null);
|
||||
|
||||
if (successes.length > 0 && failures.length === 0) {
|
||||
handleSuccess(successes);
|
||||
// handleSuccess(successes);
|
||||
setSuccessState({
|
||||
allSuccess: true,
|
||||
repoUrl: successes[0].data.urls?.repositoryURL,
|
||||
});
|
||||
} else if (failures.length > 0) {
|
||||
setFailureResults(failures);
|
||||
}
|
||||
};
|
||||
|
||||
const getPostSubmitContent = () => {
|
||||
if (progress) {
|
||||
return <BulkActionProgress progress={progress} />;
|
||||
}
|
||||
|
||||
if (successState.allSuccess) {
|
||||
return (
|
||||
<>
|
||||
<Alert severity="success" title={t('browse-dashboards.bulk-delete-resources-form.progress-title', 'Success')}>
|
||||
<Trans i18nKey="browse-dashboards.bulk-delete-resources-form.success-message">
|
||||
All resources have been deleted successfully.
|
||||
</Trans>
|
||||
</Alert>
|
||||
<Stack gap={2}>
|
||||
<Button onClick={() => handleSuccess()}>
|
||||
<Trans i18nKey="browse-dashboards.bulk-delete-resources-form.button-done">Done</Trans>
|
||||
</Button>
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
} else if (failureResults) {
|
||||
return <BulkActionFailureBanner result={failureResults} onDismiss={() => setFailureResults(undefined)} />;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
return (
|
||||
<FormProvider {...methods}>
|
||||
<form onSubmit={handleSubmit(handleSubmitForm)}>
|
||||
@@ -192,31 +224,31 @@ function FormContent({
|
||||
<DescendantCount selectedItems={{ ...selectedItems, panel: {}, $all: false }} />
|
||||
</Box>
|
||||
|
||||
{failureResults && (
|
||||
<BulkActionFailureBanner result={failureResults} onDismiss={() => setFailureResults(undefined)} />
|
||||
{hasSubmitted ? (
|
||||
getPostSubmitContent()
|
||||
) : (
|
||||
<>
|
||||
<ResourceEditFormSharedFields
|
||||
resourceType="folder"
|
||||
isNew={false}
|
||||
workflow={workflow}
|
||||
workflowOptions={workflowOptions}
|
||||
isGitHub={isGitHub}
|
||||
hidePath
|
||||
/>
|
||||
|
||||
<Stack gap={2}>
|
||||
<Button type="submit" disabled={request.isLoading || !!failureResults} variant="destructive">
|
||||
{request.isLoading
|
||||
? t('browse-dashboards.bulk-delete-resources-form.button-deleting', 'Deleting...')
|
||||
: t('browse-dashboards.bulk-delete-resources-form.button-delete', 'Delete')}
|
||||
</Button>
|
||||
<Button variant="secondary" fill="outline" onClick={onDismiss} disabled={request.isLoading}>
|
||||
<Trans i18nKey="browse-dashboards.bulk-delete-resources-form.button-cancel">Cancel</Trans>
|
||||
</Button>
|
||||
</Stack>
|
||||
</>
|
||||
)}
|
||||
|
||||
{progress && <BulkActionProgress progress={progress} />}
|
||||
|
||||
<ResourceEditFormSharedFields
|
||||
resourceType="folder"
|
||||
isNew={false}
|
||||
workflow={workflow}
|
||||
workflowOptions={workflowOptions}
|
||||
isGitHub={isGitHub}
|
||||
hidePath
|
||||
/>
|
||||
|
||||
<Stack gap={2}>
|
||||
<Button type="submit" disabled={request.isLoading || !!failureResults} variant="destructive">
|
||||
{request.isLoading
|
||||
? t('browse-dashboards.bulk-delete-resources-form.button-deleting', 'Deleting...')
|
||||
: t('browse-dashboards.bulk-delete-resources-form.button-delete', 'Delete')}
|
||||
</Button>
|
||||
<Button variant="secondary" fill="outline" onClick={onDismiss}>
|
||||
<Trans i18nKey="browse-dashboards.bulk-delete-resources-form.button-cancel">Cancel</Trans>
|
||||
</Button>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</form>
|
||||
</FormProvider>
|
||||
|
||||
@@ -5,9 +5,10 @@ import { useStyles2 } from '@grafana/ui';
|
||||
|
||||
interface ProgressBarProps {
|
||||
progress?: number;
|
||||
topBottomSpacing?: number;
|
||||
}
|
||||
const ProgressBar = ({ progress }: ProgressBarProps) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
const ProgressBar = ({ progress, topBottomSpacing }: ProgressBarProps) => {
|
||||
const styles = useStyles2(getStyles, topBottomSpacing);
|
||||
|
||||
if (progress === undefined) {
|
||||
return null;
|
||||
@@ -20,14 +21,14 @@ const ProgressBar = ({ progress }: ProgressBarProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2) => ({
|
||||
const getStyles = (theme: GrafanaTheme2, topBottomSpacing = 2) => ({
|
||||
container: css({
|
||||
height: '10px',
|
||||
width: '400px',
|
||||
backgroundColor: theme.colors.background.secondary,
|
||||
borderRadius: theme.shape.radius.pill,
|
||||
overflow: 'hidden',
|
||||
margin: theme.spacing(2, 0),
|
||||
margin: theme.spacing(topBottomSpacing, 0),
|
||||
}),
|
||||
filler: css({
|
||||
height: '100%',
|
||||
|
||||
@@ -3516,15 +3516,17 @@
|
||||
"failed-alert_other": "{{count}} items failed"
|
||||
},
|
||||
"bulk-delete-resources-form": {
|
||||
"api-success_one": "Successfully deleted {{count}} item",
|
||||
"api-success_other": "Successfully deleted {{count}} items",
|
||||
"button-cancel": "Cancel",
|
||||
"button-delete": "Delete",
|
||||
"button-deleting": "Deleting...",
|
||||
"button-done": "Done",
|
||||
"delete-warning": "This will delete selected folders and their descendants. In total, this will affect:",
|
||||
"error-path-not-found": "Path not found"
|
||||
"error-path-not-found": "Path not found",
|
||||
"progress-title": "Success",
|
||||
"success-message": "All resources have been deleted successfully."
|
||||
},
|
||||
"bulk-move-resources-form": {
|
||||
"deleting": "Deleting:",
|
||||
"progress": "Progress: {{current}} of {{total}}"
|
||||
},
|
||||
"counts": {
|
||||
|
||||
Reference in New Issue
Block a user