mirror of
https://github.com/arc53/DocsGPT.git
synced 2025-11-29 08:33:20 +00:00
(feat:upload) dismiss, but notify on completion
This commit is contained in:
@@ -4,7 +4,7 @@ import { useDispatch, useSelector } from 'react-redux';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import {
|
import {
|
||||||
selectUploadTasks,
|
selectUploadTasks,
|
||||||
removeUploadTask,
|
dismissUploadTask,
|
||||||
clearCompletedTasks,
|
clearCompletedTasks,
|
||||||
} from '../upload/uploadSlice';
|
} from '../upload/uploadSlice';
|
||||||
import ChevronDown from '../assets/chevron-down.svg';
|
import ChevronDown from '../assets/chevron-down.svg';
|
||||||
@@ -30,8 +30,6 @@ export default function UploadToast() {
|
|||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const uploadTasks = useSelector(selectUploadTasks);
|
const uploadTasks = useSelector(selectUploadTasks);
|
||||||
|
|
||||||
if (uploadTasks.length === 0) return null;
|
|
||||||
|
|
||||||
const getStatusHeading = (status: string) => {
|
const getStatusHeading = (status: string) => {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 'preparing':
|
case 'preparing':
|
||||||
@@ -51,7 +49,9 @@ export default function UploadToast() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="fixed right-4 bottom-4 z-50 flex max-w-md flex-col gap-2">
|
<div className="fixed right-4 bottom-4 z-50 flex max-w-md flex-col gap-2">
|
||||||
{uploadTasks.map((task) => {
|
{uploadTasks
|
||||||
|
.filter((task) => !task.dismissed)
|
||||||
|
.map((task) => {
|
||||||
const shouldShowProgress = [
|
const shouldShowProgress = [
|
||||||
'preparing',
|
'preparing',
|
||||||
'uploading',
|
'uploading',
|
||||||
@@ -59,7 +59,8 @@ export default function UploadToast() {
|
|||||||
].includes(task.status);
|
].includes(task.status);
|
||||||
const rawProgress = Math.min(Math.max(task.progress ?? 0, 0), 100);
|
const rawProgress = Math.min(Math.max(task.progress ?? 0, 0), 100);
|
||||||
const formattedProgress = Math.round(rawProgress);
|
const formattedProgress = Math.round(rawProgress);
|
||||||
const progressOffset = PROGRESS_CIRCUMFERENCE * (1 - rawProgress / 100);
|
const progressOffset =
|
||||||
|
PROGRESS_CIRCUMFERENCE * (1 - rawProgress / 100);
|
||||||
const isCollapsed = collapsedTasks[task.id] ?? false;
|
const isCollapsed = collapsedTasks[task.id] ?? false;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -103,11 +104,9 @@ export default function UploadToast() {
|
|||||||
}`}
|
}`}
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
{(task.status === 'completed' ||
|
|
||||||
task.status === 'failed') && (
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => dispatch(removeUploadTask(task.id))}
|
onClick={() => dispatch(dismissUploadTask(task.id))}
|
||||||
className="flex h-8 items-center justify-center p-0 text-black opacity-70 transition-opacity hover:opacity-100 dark:text-white"
|
className="flex h-8 items-center justify-center p-0 text-black opacity-70 transition-opacity hover:opacity-100 dark:text-white"
|
||||||
aria-label="Dismiss upload toast"
|
aria-label="Dismiss upload toast"
|
||||||
>
|
>
|
||||||
@@ -135,7 +134,6 @@ export default function UploadToast() {
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ export interface UploadTask {
|
|||||||
status: UploadTaskStatus;
|
status: UploadTaskStatus;
|
||||||
taskId?: string;
|
taskId?: string;
|
||||||
errorMessage?: string;
|
errorMessage?: string;
|
||||||
|
dismissed?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UploadState {
|
interface UploadState {
|
||||||
@@ -84,9 +85,29 @@ export const uploadSlice = createSlice({
|
|||||||
(task) => task.id === action.payload.id,
|
(task) => task.id === action.payload.id,
|
||||||
);
|
);
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
|
const updates = action.payload.updates;
|
||||||
|
|
||||||
|
// When task completes or fails, set dismissed to false to notify user
|
||||||
|
if (updates.status === 'completed' || updates.status === 'failed') {
|
||||||
state.tasks[index] = {
|
state.tasks[index] = {
|
||||||
...state.tasks[index],
|
...state.tasks[index],
|
||||||
...action.payload.updates,
|
...updates,
|
||||||
|
dismissed: false,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
state.tasks[index] = {
|
||||||
|
...state.tasks[index],
|
||||||
|
...updates,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dismissUploadTask: (state, action: PayloadAction<string>) => {
|
||||||
|
const index = state.tasks.findIndex((task) => task.id === action.payload);
|
||||||
|
if (index !== -1) {
|
||||||
|
state.tasks[index] = {
|
||||||
|
...state.tasks[index],
|
||||||
|
dismissed: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -111,6 +132,7 @@ export const {
|
|||||||
clearAttachments,
|
clearAttachments,
|
||||||
addUploadTask,
|
addUploadTask,
|
||||||
updateUploadTask,
|
updateUploadTask,
|
||||||
|
dismissUploadTask,
|
||||||
removeUploadTask,
|
removeUploadTask,
|
||||||
clearCompletedTasks,
|
clearCompletedTasks,
|
||||||
} = uploadSlice.actions;
|
} = uploadSlice.actions;
|
||||||
|
|||||||
Reference in New Issue
Block a user