Skip to content

Commit 3425826

Browse files
committed
refac
1 parent 60e4d75 commit 3425826

1 file changed

Lines changed: 76 additions & 14 deletions

File tree

src/lib/components/admin/Evaluations/Feedbacks.svelte

Lines changed: 76 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import FeedbackMenu from './FeedbackMenu.svelte';
2626
import FeedbackModal from './FeedbackModal.svelte';
2727
import EllipsisHorizontal from '$lib/components/icons/EllipsisHorizontal.svelte';
28+
import Dropdown from '$lib/components/common/Dropdown.svelte';
2829
2930
import ChevronUp from '$lib/components/icons/ChevronUp.svelte';
3031
import ChevronDown from '$lib/components/icons/ChevronDown.svelte';
@@ -148,7 +149,40 @@
148149
window.addEventListener('message', messageHandler, false);
149150
};
150151
151-
const exportHandler = async () => {
152+
const feedbacksToCsv = (feedbacks) => {
153+
const rows = feedbacks.map((f) => {
154+
const { data, ...rest } = f;
155+
return {
156+
id: rest.id,
157+
user_id: rest.user_id,
158+
chat_id: data?.chat_id ?? '',
159+
model_id: data?.model_id ?? '',
160+
sibling_model_ids: (data?.sibling_model_ids ?? []).join(';'),
161+
rating: data?.rating ?? '',
162+
reason: data?.reason ?? '',
163+
comment: data?.comment ?? '',
164+
created_at: rest.created_at,
165+
updated_at: rest.updated_at
166+
};
167+
});
168+
169+
if (rows.length === 0) return '';
170+
171+
const headers = Object.keys(rows[0]);
172+
const escape = (val) => {
173+
const s = String(val ?? '');
174+
return s.includes(',') || s.includes('"') || s.includes('\n')
175+
? `"${s.replace(/"/g, '""')}"`
176+
: s;
177+
};
178+
179+
return [
180+
headers.join(','),
181+
...rows.map((r) => headers.map((h) => escape(r[h])).join(','))
182+
].join('\n');
183+
};
184+
185+
const exportHandler = async (format: 'json' | 'csv' = 'json') => {
152186
const _feedbacks = await exportAllFeedbacks(localStorage.token, selectedModelId).catch(
153187
(err) => {
154188
toast.error(err);
@@ -157,10 +191,16 @@
157191
);
158192
159193
if (_feedbacks) {
160-
let blob = new Blob([JSON.stringify(_feedbacks)], {
161-
type: 'application/json'
162-
});
163-
saveAs(blob, `feedback-history-export-${Date.now()}.json`);
194+
if (format === 'csv') {
195+
const csv = feedbacksToCsv(_feedbacks);
196+
let blob = new Blob([csv], { type: 'text/csv' });
197+
saveAs(blob, `feedback-history-export-${Date.now()}.csv`);
198+
} else {
199+
let blob = new Blob([JSON.stringify(_feedbacks)], {
200+
type: 'application/json'
201+
});
202+
saveAs(blob, `feedback-history-export-${Date.now()}.json`);
203+
}
164204
}
165205
};
166206
@@ -190,16 +230,38 @@
190230

191231
<div class="flex w-full justify-end gap-1.5">
192232
{#if total > 0}
193-
<button
194-
class="flex text-xs items-center space-x-1 px-3 py-1.5 rounded-xl bg-gray-50 hover:bg-gray-100 dark:bg-gray-850 dark:hover:bg-gray-800 dark:text-gray-200 transition"
195-
on:click={() => {
196-
exportHandler();
197-
}}
198-
>
199-
<div class="self-center font-medium line-clamp-1">
200-
{$i18n.t('Export')}
233+
<Dropdown align="end">
234+
<button
235+
class="flex text-xs items-center space-x-1 px-3 py-1.5 rounded-xl bg-gray-50 hover:bg-gray-100 dark:bg-gray-850 dark:hover:bg-gray-800 dark:text-gray-200 transition"
236+
>
237+
<div class="self-center font-medium line-clamp-1">
238+
{$i18n.t('Export')}
239+
</div>
240+
<ChevronDown className="size-3" strokeWidth="2.5" />
241+
</button>
242+
243+
<div slot="content">
244+
<div
245+
class="w-[170px] rounded-2xl p-1 border border-gray-100 dark:border-gray-800 z-50 bg-white dark:bg-gray-850 dark:text-white shadow-lg"
246+
>
247+
<button
248+
class="select-none flex w-full gap-2 items-center px-3 py-1.5 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-xl"
249+
type="button"
250+
on:click={() => exportHandler('json')}
251+
>
252+
{$i18n.t('Export as JSON')}
253+
</button>
254+
255+
<button
256+
class="select-none flex w-full gap-2 items-center px-3 py-1.5 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-xl"
257+
type="button"
258+
on:click={() => exportHandler('csv')}
259+
>
260+
{$i18n.t('Export as CSV')}
261+
</button>
262+
</div>
201263
</div>
202-
</button>
264+
</Dropdown>
203265
{/if}
204266
</div>
205267
</div>

0 commit comments

Comments
 (0)