Skip to content

Commit f0e3544

Browse files
authored
Merge branch 'main' into feat/pay
2 parents 916377e + 7d67fd0 commit f0e3544

File tree

9 files changed

+310
-237
lines changed

9 files changed

+310
-237
lines changed

.github/workflows/ci.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ on:
1111
- 'main'
1212

1313
concurrency:
14-
group: registry-push-${{ github.ref }}
14+
group: registry-push
1515
cancel-in-progress: true
1616

1717
jobs:
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
import { LoaderCircle } from 'lucide-react';
2+
import { useState } from 'react';
3+
import { Trans, useTranslation } from 'react-i18next';
4+
import { toast } from 'sonner';
5+
6+
import {
7+
AlertDialog,
8+
AlertDialogAction,
9+
AlertDialogCancel,
10+
AlertDialogContent,
11+
AlertDialogDescription,
12+
AlertDialogFooter,
13+
AlertDialogHeader,
14+
AlertDialogTitle,
15+
} from '@/components/ui/alert-dialog';
16+
import { http } from '@/lib/request';
17+
18+
interface IProps {
19+
open: boolean;
20+
titleKey?: string;
21+
descriptionKey?: string;
22+
targetName: string;
23+
itemTitle: string;
24+
deleteUrl: string;
25+
restoreUrl?: string;
26+
successMessage?: string;
27+
successDescription?: string;
28+
onOpenChange: (open: boolean) => void;
29+
onSuccess?: () => void;
30+
onRestoreSuccess?: (response?: any) => void;
31+
onError?: (error: any) => void;
32+
}
33+
34+
export default function ConfirmDeleteDialog(props: IProps) {
35+
const {
36+
open,
37+
titleKey,
38+
targetName,
39+
descriptionKey,
40+
itemTitle,
41+
deleteUrl,
42+
restoreUrl,
43+
successMessage,
44+
successDescription,
45+
onOpenChange,
46+
onSuccess,
47+
onRestoreSuccess,
48+
onError,
49+
} = props;
50+
const { t } = useTranslation();
51+
const [loading, setLoading] = useState(false);
52+
53+
const handleCancel = () => {
54+
onOpenChange(false);
55+
};
56+
57+
const handleConfirm = () => {
58+
setLoading(true);
59+
http
60+
.delete(deleteUrl)
61+
.then(() => {
62+
onOpenChange(false);
63+
onSuccess?.();
64+
65+
// show success message
66+
const toastOptions: any = {
67+
description: successDescription,
68+
};
69+
70+
// if restore url is provided, add undo function
71+
if (restoreUrl) {
72+
toastOptions.action = {
73+
label: t('undo'),
74+
onClick: () => {
75+
http.post(restoreUrl).then(response => {
76+
if (onRestoreSuccess) {
77+
onRestoreSuccess(response);
78+
} else {
79+
onSuccess?.();
80+
}
81+
});
82+
},
83+
};
84+
}
85+
86+
toast(successMessage, toastOptions);
87+
})
88+
.catch(error => {
89+
onError?.(error);
90+
toast.error(t('error.title'), {
91+
description: error.message || t('request.failed'),
92+
});
93+
})
94+
.finally(() => {
95+
setLoading(false);
96+
});
97+
};
98+
99+
return (
100+
<AlertDialog open={open} onOpenChange={onOpenChange}>
101+
<AlertDialogContent>
102+
<AlertDialogHeader>
103+
<AlertDialogTitle>
104+
<Trans
105+
i18nKey={titleKey || 'common.dialog.delete.title'}
106+
values={{ target_name: targetName }}
107+
/>
108+
</AlertDialogTitle>
109+
<AlertDialogDescription>
110+
<Trans
111+
i18nKey={descriptionKey || 'common.dialog.delete.description'}
112+
values={{ title: itemTitle }}
113+
components={{
114+
strong: <strong className="font-bold" />,
115+
}}
116+
/>
117+
</AlertDialogDescription>
118+
</AlertDialogHeader>
119+
<AlertDialogFooter>
120+
<AlertDialogCancel onClick={handleCancel}>
121+
{t('cancel')}
122+
</AlertDialogCancel>
123+
<AlertDialogAction
124+
disabled={loading}
125+
onClick={handleConfirm}
126+
className="bg-red-500 text-white hover:bg-red-600"
127+
>
128+
{loading && <LoaderCircle className="mr-2 h-4 w-4 animate-spin" />}
129+
{t('delete')}
130+
</AlertDialogAction>
131+
</AlertDialogFooter>
132+
</AlertDialogContent>
133+
</AlertDialog>
134+
);
135+
}

src/i18n/locales/en.json

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@
2222
"invalid_ext": "Invalid file type"
2323
},
2424
"resource": {
25+
"name": "Resource",
2526
"folder": {
2627
"children_count": "{{ count }} files"
2728
},
2829
"deleted": "Deleted",
2930
"deleted_description": "This resource has been deleted",
3031
"no_content": "Resource has no content to download",
32+
"untitled": "Untitled",
3133
"attrs": {
3234
"tag": "Tag",
3335
"add_tag": "Add tag",
@@ -371,18 +373,15 @@
371373
}
372374
},
373375
"conversations": {
376+
"name": "Conversation",
374377
"new": "New conversation",
375378
"new_chat": "New Chat",
376379
"empty": "No conversation yet",
377380
"history": "Chat History",
378381
"deleted": "Deleted Conversations",
379382
"deleted_description": "This conversation has been deleted",
380383
"delete": {
381-
"option": "Delete",
382-
"dialog": {
383-
"title": "Delete conversation?",
384-
"description": "All your <strong>{{ title }}</strong> history will be deleted, This cannot be undo."
385-
}
384+
"option": "Delete"
386385
},
387386
"rename": {
388387
"option": "Rename",
@@ -535,7 +534,13 @@
535534
"refresh": "Refresh",
536535
"retry": "Retry",
537536
"previous": "Previous",
538-
"next": "Next"
537+
"next": "Next",
538+
"dialog": {
539+
"delete": {
540+
"title": "Delete {{target_name}}?",
541+
"description": "You are going to delete <strong>{{title}}</strong>"
542+
}
543+
}
539544
},
540545
"loading": "Loading...",
541546
"creating": "Creating...",

src/i18n/locales/zh.json

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@
2222
"invalid_ext": "当前文件格式不支持"
2323
},
2424
"resource": {
25+
"name": "文件",
2526
"folder": {
2627
"children_count": "{{ count }} 个文件"
2728
},
2829
"deleted": "已删除",
2930
"deleted_description": "此资源已被删除",
3031
"no_content": "资源没有内容可下载",
32+
"untitled": "未命名",
3133
"attrs": {
3234
"tag": "标签",
3335
"add_tag": "点击添加标签",
@@ -371,18 +373,15 @@
371373
}
372374
},
373375
"conversations": {
376+
"name": "会话",
374377
"new": "新对话",
375378
"new_chat": "新建对话",
376379
"empty": "暂无对话",
377380
"history": "聊天历史",
378381
"deleted": "已删除对话",
379382
"deleted_description": "此对话已被删除",
380383
"delete": {
381-
"option": "删除对话",
382-
"dialog": {
383-
"title": "确定删除对话?",
384-
"description": "正在删除 <strong>{{ title }}</strong>,删除后,聊天记录将不可恢复。"
385-
}
384+
"option": "删除对话"
386385
},
387386
"rename": {
388387
"option": "重命名",
@@ -535,7 +534,13 @@
535534
"refresh": "刷新",
536535
"retry": "重试",
537536
"previous": "上一页",
538-
"next": "下一页"
537+
"next": "下一页",
538+
"dialog": {
539+
"delete": {
540+
"title": "删除{{target_name}}?",
541+
"description": "您将要删除 <strong>{{title}}</strong>"
542+
}
543+
}
539544
},
540545
"loading": "加载中...",
541546
"creating": "创建中...",
Lines changed: 13 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,6 @@
1-
import { LoaderCircle } from 'lucide-react';
2-
import { useState } from 'react';
3-
import { Trans, useTranslation } from 'react-i18next';
4-
import { toast } from 'sonner';
1+
import { useTranslation } from 'react-i18next';
52

6-
import {
7-
AlertDialog,
8-
AlertDialogAction,
9-
AlertDialogCancel,
10-
AlertDialogContent,
11-
AlertDialogDescription,
12-
AlertDialogFooter,
13-
AlertDialogHeader,
14-
AlertDialogTitle,
15-
} from '@/components/ui/alert-dialog';
16-
import { http } from '@/lib/request';
3+
import ConfirmDeleteDialog from '@/components/confirm-delete-dialog';
174

185
interface IProps {
196
data: {
@@ -29,68 +16,18 @@ interface IProps {
2916
export default function RemoveHistory(props: IProps) {
3017
const { data, namespaceId, onFinish, onOpenChange } = props;
3118
const { t } = useTranslation();
32-
const [loading, onLoading] = useState(false);
33-
const handleCancel = () => {
34-
onOpenChange(false);
35-
};
36-
const handleRemove = () => {
37-
onLoading(true);
38-
http
39-
.delete(`namespaces/${namespaceId}/conversations/${data.id}`)
40-
.then(() => {
41-
onFinish();
42-
toast(t('chat.conversations.deleted'), {
43-
description: t('chat.conversations.deleted_description'),
44-
action: {
45-
label: t('undo'),
46-
onClick: () => {
47-
http
48-
.post(
49-
`/namespaces/${namespaceId}/conversations/${data.id}/restore`
50-
)
51-
.then(onFinish);
52-
},
53-
},
54-
});
55-
})
56-
.finally(() => {
57-
onLoading(false);
58-
});
59-
};
6019

6120
return (
62-
<AlertDialog open={data.open}>
63-
<AlertDialogContent>
64-
<AlertDialogHeader>
65-
<AlertDialogTitle>
66-
{t('chat.conversations.delete.dialog.title')}
67-
</AlertDialogTitle>
68-
<AlertDialogDescription>
69-
<Trans
70-
i18nKey="chat.conversations.delete.dialog.description"
71-
values={{ title: data.title }}
72-
components={{
73-
strong: <strong className="font-bold" />,
74-
}}
75-
/>
76-
</AlertDialogDescription>
77-
</AlertDialogHeader>
78-
<AlertDialogFooter>
79-
<AlertDialogCancel onClick={handleCancel}>
80-
{t('cancel')}
81-
</AlertDialogCancel>
82-
<AlertDialogAction
83-
disabled={loading}
84-
onClick={handleRemove}
85-
className="bg-red-500 text-white"
86-
>
87-
{loading && (
88-
<LoaderCircle className="transition-transform animate-spin" />
89-
)}
90-
{t('delete')}
91-
</AlertDialogAction>
92-
</AlertDialogFooter>
93-
</AlertDialogContent>
94-
</AlertDialog>
21+
<ConfirmDeleteDialog
22+
open={data.open}
23+
targetName={t('chat.conversations.name')}
24+
itemTitle={data.title}
25+
deleteUrl={`namespaces/${namespaceId}/conversations/${data.id}`}
26+
restoreUrl={`/namespaces/${namespaceId}/conversations/${data.id}/restore`}
27+
successMessage={t('chat.conversations.deleted')}
28+
successDescription={t('chat.conversations.deleted_description')}
29+
onOpenChange={onOpenChange}
30+
onSuccess={onFinish}
31+
/>
9532
);
9633
}

0 commit comments

Comments
 (0)