ManageModal.svelte 5.47 KB
Newer Older
1
2
3
4
5
6
7
8
<script lang="ts">
	import { toast } from 'svelte-sonner';
	import dayjs from 'dayjs';
	import { getContext, createEventDispatcher } from 'svelte';

	const dispatch = createEventDispatcher();

	import Modal from '$lib/components/common/Modal.svelte';
Timothy J. Baek's avatar
Timothy J. Baek committed
9
	import AddMemoryModal from './AddMemoryModal.svelte';
Timothy J. Baek's avatar
Timothy J. Baek committed
10
	import { deleteMemoriesByUserId, deleteMemoryById, getMemories } from '$lib/apis/memories';
Timothy J. Baek's avatar
Timothy J. Baek committed
11
12
	import Tooltip from '$lib/components/common/Tooltip.svelte';
	import { error } from '@sveltejs/kit';
13
14
15
16
17
18
19

	const i18n = getContext('i18n');

	export let show = false;

	let memories = [];

Timothy J. Baek's avatar
Timothy J. Baek committed
20
21
	let showAddMemoryModal = false;

22
23
	$: if (show) {
		(async () => {
Timothy J. Baek's avatar
Timothy J. Baek committed
24
			memories = await getMemories(localStorage.token);
25
26
27
28
		})();
	}
</script>

Timothy J. Baek's avatar
Timothy J. Baek committed
29
<Modal size="xl" bind:show>
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
	<div>
		<div class=" flex justify-between dark:text-gray-300 px-5 pt-4 pb-1">
			<div class=" text-lg font-medium self-center">{$i18n.t('Memory')}</div>
			<button
				class="self-center"
				on:click={() => {
					show = false;
				}}
			>
				<svg
					xmlns="http://www.w3.org/2000/svg"
					viewBox="0 0 20 20"
					fill="currentColor"
					class="w-5 h-5"
				>
					<path
						d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z"
					/>
				</svg>
			</button>
		</div>

Timothy J. Baek's avatar
Timothy J. Baek committed
52
53
54
55
56
		<div class="flex flex-col w-full px-5 pb-5 dark:text-gray-200">
			<div
				class=" flex flex-col w-full sm:flex-row sm:justify-center sm:space-x-6 h-[28rem] max-h-screen outline outline-1 rounded-xl outline-gray-100 dark:outline-gray-800 mb-4 mt-1"
			>
				{#if memories.length > 0}
57
58
59
60
61
62
63
64
65
66
67
68
69
					<div class="text-left text-sm w-full mb-4 max-h-[22rem] overflow-y-scroll">
						<div class="relative overflow-x-auto">
							<table class="w-full text-sm text-left text-gray-600 dark:text-gray-400 table-auto">
								<thead
									class="text-xs text-gray-700 uppercase bg-transparent dark:text-gray-200 border-b-2 dark:border-gray-800"
								>
									<tr>
										<th scope="col" class="px-3 py-2"> {$i18n.t('Name')} </th>
										<th scope="col" class="px-3 py-2 hidden md:flex"> {$i18n.t('Created At')} </th>
										<th scope="col" class="px-3 py-2 text-right" />
									</tr>
								</thead>
								<tbody>
Timothy J. Baek's avatar
Timothy J. Baek committed
70
									{#each memories as memory}
Timothy J. Baek's avatar
Timothy J. Baek committed
71
72
73
74
75
76
										<tr class="border-b dark:border-gray-800 items-center">
											<td class="px-3 py-1"> {memory.content} </td>
											<td class=" px-3 py-1 hidden md:flex h-[2.5rem]">
												<div class="my-auto">
													{dayjs(memory.created_at * 1000).format($i18n.t('MMMM DD, YYYY'))}
												</div>
77
											</td>
Timothy J. Baek's avatar
Timothy J. Baek committed
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
											<td class="px-3 py-1">
												<div class="flex justify-end w-full">
													<Tooltip content="Delete">
														<button
															class="self-center w-fit text-sm px-2 py-2 hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
															on:click={async () => {
																const res = await deleteMemoryById(
																	localStorage.token,
																	memory.id
																).catch((error) => {
																	toast.error(error);
																	return null;
																});

																if (res) {
																	toast.success('Memory deleted successfully');
																	memories = await getMemories(localStorage.token);
																}
															}}
														>
															<svg
																xmlns="http://www.w3.org/2000/svg"
																fill="none"
																viewBox="0 0 24 24"
																stroke-width="1.5"
																stroke="currentColor"
																class="w-4 h-4"
															>
																<path
																	stroke-linecap="round"
																	stroke-linejoin="round"
																	d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0"
																/>
															</svg>
														</button>
													</Tooltip>
												</div>
115
116
117
118
119
120
121
122
											</td>
										</tr>
									{/each}
								</tbody>
							</table>
						</div>
					</div>
				{:else}
Timothy J. Baek's avatar
Timothy J. Baek committed
123
124
					<div class="text-center flex h-full text-sm w-full">
						<div class=" my-auto pb-10 px-4 w-full text-gray-500">
Timothy J. Baek's avatar
Timothy J. Baek committed
125
							{$i18n.t('Memories accessible by LLMs will be shown here.')}
Timothy J. Baek's avatar
Timothy J. Baek committed
126
						</div>
127
128
129
					</div>
				{/if}
			</div>
Timothy J. Baek's avatar
Timothy J. Baek committed
130
131
132
133
134
135
136
			<div class="flex text-sm font-medium gap-1.5">
				<button
					class=" px-3.5 py-1.5 font-medium hover:bg-black/5 dark:hover:bg-white/5 outline outline-1 outline-gray-300 dark:outline-gray-800 rounded-3xl"
					on:click={() => {
						showAddMemoryModal = true;
					}}>Add memory</button
				>
Timothy J. Baek's avatar
Timothy J. Baek committed
137
				<button
Timothy J. Baek's avatar
Timothy J. Baek committed
138
					class=" px-3.5 py-1.5 font-medium text-red-500 hover:bg-black/5 dark:hover:bg-white/5 outline outline-1 outline-red-300 dark:outline-red-800 rounded-3xl"
Timothy J. Baek's avatar
Timothy J. Baek committed
139
140
141
142
143
144
145
146
147
148
149
150
					on:click={async () => {
						const res = await deleteMemoriesByUserId(localStorage.token).catch((error) => {
							toast.error(error);
							return null;
						});

						if (res) {
							toast.success('Memory cleared successfully');
							memories = [];
						}
					}}>Clear memory</button
				>
Timothy J. Baek's avatar
Timothy J. Baek committed
151
			</div>
152
153
154
		</div>
	</div>
</Modal>
Timothy J. Baek's avatar
Timothy J. Baek committed
155

Timothy J. Baek's avatar
Timothy J. Baek committed
156
157
158
159
160
161
<AddMemoryModal
	bind:show={showAddMemoryModal}
	on:save={async () => {
		memories = await getMemories(localStorage.token);
	}}
/>