@rkosafo/cai.components 0.0.78 → 0.0.80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/dist/baseEditor/index.svelte +32 -32
- package/dist/builders/filters/FilterBuilder.svelte +641 -641
- package/dist/forms/FormCheckbox/FormCheckbox.svelte +53 -53
- package/dist/forms/FormClEditor/ClEdito.svelte +68 -68
- package/dist/forms/FormDatepicker/FormDatepicker.svelte +159 -159
- package/dist/forms/FormFileUpload/FormFileUplad.svelte +134 -134
- package/dist/forms/FormInput/FormInput.svelte +87 -87
- package/dist/forms/FormRadio/FormRadio.svelte +53 -53
- package/dist/forms/FormSelect/FormSelect.svelte +88 -88
- package/dist/forms/FormTextarea/FormTextarea.svelte +78 -78
- package/dist/forms/button-toggle/ButtonToggle.svelte +119 -119
- package/dist/forms/button-toggle/CheckIcon.svelte +28 -28
- package/dist/forms/checkbox/Checkbox.svelte +82 -82
- package/dist/forms/checkbox/CheckboxButton.svelte +92 -92
- package/dist/forms/datepicker/Datepicker.svelte +707 -707
- package/dist/forms/form/Form.svelte +69 -69
- package/dist/forms/input/Input.svelte +363 -363
- package/dist/forms/label/Label.svelte +38 -38
- package/dist/forms/radio/Radio.svelte +48 -48
- package/dist/forms/radio/RadioButton.svelte +22 -22
- package/dist/forms/select/Select.svelte +56 -56
- package/dist/forms/textarea/Textarea.svelte +165 -165
- package/dist/forms/toggle/Toggle.svelte +70 -70
- package/dist/layout/Chat/CategorySelector.svelte +52 -52
- package/dist/layout/Chat/ChatEntry.svelte +246 -246
- package/dist/layout/Chat/ChatEntrySkeleton.svelte +81 -81
- package/dist/layout/Chat/ChatHeader.svelte +172 -172
- package/dist/layout/Chat/ChatInput.svelte +207 -207
- package/dist/layout/Chat/DraggableWindow.svelte +230 -230
- package/dist/layout/Chat/PreviewPage.svelte +182 -182
- package/dist/layout/Chat/RichText.svelte +216 -216
- package/dist/layout/ComponentCanvas/Canvas.svelte +40 -40
- package/dist/layout/ComponentCanvas/ComponentRenderer.svelte +85 -85
- package/dist/layout/TF/Content/Content.svelte +21 -21
- package/dist/layout/TF/Header/Header.svelte +166 -166
- package/dist/layout/TF/Sidebar/Sidebar.svelte +148 -148
- package/dist/layout/TF/Wrapper/Wrapper.svelte +17 -17
- package/dist/layout/mailing/MailPaginator.svelte +36 -36
- package/dist/layout/mailing/MailSidebar.svelte +39 -39
- package/dist/layout/mailing/MailToolBar.svelte +174 -174
- package/dist/layout/mailing/MailingContent.svelte +10 -10
- package/dist/layout/mailing/MailingHeader.svelte +55 -55
- package/dist/layout/mailing/MailingMessageCard.svelte +112 -112
- package/dist/layout/mailing/MailingMessageViewer.svelte +87 -87
- package/dist/layout/mailing/MailingModule.svelte +448 -448
- package/dist/styles/docs.css +615 -615
- package/dist/styles/tf-layout.css +185 -185
- package/dist/themes/ThemeProvider.svelte +20 -20
- package/dist/types/index.d.ts +2 -0
- package/dist/typography/heading/Heading.svelte +35 -35
- package/dist/ui/accordion/Accordion.svelte +49 -49
- package/dist/ui/accordion/AccordionItem.svelte +173 -173
- package/dist/ui/alert/Alert.svelte +83 -83
- package/dist/ui/alertDialog/AlertDialog.svelte +40 -40
- package/dist/ui/avatar/Avatar.svelte +77 -77
- package/dist/ui/box/Box.svelte +28 -28
- package/dist/ui/breadcrumb/Breadcrumb.svelte +39 -39
- package/dist/ui/buttons/ActionButton.svelte +234 -234
- package/dist/ui/buttons/Button.svelte +102 -102
- package/dist/ui/buttons/GradientButton.svelte +59 -59
- package/dist/ui/datatable/Datatable.svelte +525 -525
- package/dist/ui/drawer/Drawer.svelte +300 -300
- package/dist/ui/dropdown/Dropdown.svelte +36 -36
- package/dist/ui/dropdown/DropdownDivider.svelte +11 -11
- package/dist/ui/dropdown/DropdownGroup.svelte +14 -14
- package/dist/ui/dropdown/DropdownHeader.svelte +14 -14
- package/dist/ui/dropdown/DropdownItem.svelte +52 -52
- package/dist/ui/footer/Footer.svelte +15 -15
- package/dist/ui/footer/FooterBrand.svelte +37 -37
- package/dist/ui/footer/FooterCopyright.svelte +45 -45
- package/dist/ui/footer/FooterIcon.svelte +22 -22
- package/dist/ui/footer/FooterLink.svelte +33 -33
- package/dist/ui/footer/FooterLinkGroup.svelte +13 -13
- package/dist/ui/icons/IconifyIcon.svelte +7 -7
- package/dist/ui/indicator/Indicator.svelte +42 -42
- package/dist/ui/modal/Modal.svelte +265 -265
- package/dist/ui/notificationList/NotificationList.svelte +123 -123
- package/dist/ui/pageLoader/PageLoader.svelte +14 -14
- package/dist/ui/pageLoader/PageLoader2.svelte +99 -0
- package/dist/ui/pageLoader/PageLoader2.svelte.d.ts +24 -0
- package/dist/ui/pageLoader/index.d.ts +2 -1
- package/dist/ui/pageLoader/index.js +2 -1
- package/dist/ui/paginate/Paginate.svelte +96 -96
- package/dist/ui/speedDial/SpeedDial.svelte +77 -77
- package/dist/ui/speedDial/SpeedDialButton.svelte +75 -75
- package/dist/ui/speedDial/SpeedDialTrigger.svelte +79 -79
- package/dist/ui/tab/Tab.svelte +93 -67
- package/dist/ui/table/Table.svelte +396 -396
- package/dist/ui/tableLoader/TableLoader.svelte +24 -24
- package/dist/ui/toast/Toast.svelte +337 -337
- package/dist/ui/toast/Toast.svelte.d.ts +10 -10
- package/dist/ui/toolbar/Toolbar.svelte +59 -59
- package/dist/ui/toolbar/ToolbarButton.svelte +56 -56
- package/dist/ui/toolbar/ToolbarGroup.svelte +43 -43
- package/dist/ui/tooltip/Tooltip.svelte +51 -51
- package/dist/utils/Popper.svelte +257 -257
- package/dist/utils/closeButton/CloseButton.svelte +88 -88
- package/dist/utils/index.d.ts +2 -2
- package/dist/utils/index.js +3 -3
- package/dist/utils/singleSelection.svelte.js +48 -48
- package/dist/youtube/index.svelte +12 -12
- package/package.json +1 -1
|
@@ -1,448 +1,448 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { PageLoader } from '../../ui/pageLoader/index.js';
|
|
3
|
-
import { scale, slide } from 'svelte/transition';
|
|
4
|
-
import {
|
|
5
|
-
MailSidebar,
|
|
6
|
-
MailToolBar,
|
|
7
|
-
type MailingModuleProps,
|
|
8
|
-
type MailMenu,
|
|
9
|
-
type MailingMessage,
|
|
10
|
-
type MailMarkReadToggleType,
|
|
11
|
-
type MailFavariteToggleType,
|
|
12
|
-
type MailPageInfo,
|
|
13
|
-
type MailingActiveBox
|
|
14
|
-
} from './index.js';
|
|
15
|
-
import MailingMessageCard from './MailingMessageCard.svelte';
|
|
16
|
-
import { toast, type CrudResult, type TableFilter } from '../../index.js';
|
|
17
|
-
import { PageInfo } from '../../utils/paginate.svelte.js';
|
|
18
|
-
import AlertDialog from '../../ui/alertDialog/AlertDialog.svelte';
|
|
19
|
-
import MailingMessageViewer from './MailingMessageViewer.svelte';
|
|
20
|
-
import debounce from 'lodash/debounce';
|
|
21
|
-
|
|
22
|
-
let {
|
|
23
|
-
showSidePanel = true,
|
|
24
|
-
showPagination = true,
|
|
25
|
-
showComposeButton = true,
|
|
26
|
-
showSearch = true,
|
|
27
|
-
customFilterComponent,
|
|
28
|
-
showArchiveButton = true,
|
|
29
|
-
showDeleteButton = true,
|
|
30
|
-
showMarkReadButton = true,
|
|
31
|
-
showFavoriteButton = true,
|
|
32
|
-
showMarkAsSpamButton = true,
|
|
33
|
-
showReplies = true,
|
|
34
|
-
showMarkAsImportantButton = true,
|
|
35
|
-
readInbox = $bindable((skip?: number, take?: number, filter?: TableFilter<any>) => {
|
|
36
|
-
return null;
|
|
37
|
-
}),
|
|
38
|
-
readOutbox = $bindable((skip?: number, take?: number, filter?: TableFilter<any>) => {
|
|
39
|
-
return null;
|
|
40
|
-
}),
|
|
41
|
-
deleteEntry = async (id: string | number) => {
|
|
42
|
-
return { success: false, data: null, error: null } as any;
|
|
43
|
-
},
|
|
44
|
-
toggleArchieve = async (id: string | number) => {
|
|
45
|
-
return { success: false, data: null, error: null } as any;
|
|
46
|
-
},
|
|
47
|
-
toggleAsRead = async (id: string | number, type?: MailMarkReadToggleType) => {
|
|
48
|
-
return { success: false, data: null, error: null } as any;
|
|
49
|
-
},
|
|
50
|
-
toggleFavourite = async (id: string | number) => {
|
|
51
|
-
return { success: false, data: null, error: null } as any;
|
|
52
|
-
},
|
|
53
|
-
toggleSpam = async (id: string | number) => {
|
|
54
|
-
return { success: false, data: null, error: null } as any;
|
|
55
|
-
},
|
|
56
|
-
toggelImportant = async (id: string | number) => {
|
|
57
|
-
return { success: false, data: null, error: null } as any;
|
|
58
|
-
},
|
|
59
|
-
readAMessage = async (id: string | number) => {
|
|
60
|
-
return { success: false, data: null, error: null } as any;
|
|
61
|
-
}
|
|
62
|
-
}: MailingModuleProps = $props();
|
|
63
|
-
|
|
64
|
-
let activeBox = $state<MailingActiveBox>('inbox');
|
|
65
|
-
let pageInfo = new PageInfo();
|
|
66
|
-
let menutItems = $state([
|
|
67
|
-
{ icon: 'bx:bxs-inbox', title: 'Inbox', count: 0, path: '' },
|
|
68
|
-
{ icon: 'bx:bxs-send', title: 'Sent', count: 0, path: '' }
|
|
69
|
-
]);
|
|
70
|
-
let openDeleteAlert = $state(false);
|
|
71
|
-
let busy = $state(true);
|
|
72
|
-
let messages = $state<MailingMessage[]>([]);
|
|
73
|
-
let pageNumber = $derived(pageInfo.currentPage);
|
|
74
|
-
let query = $state('');
|
|
75
|
-
let selectedMessages = $state<number[]>([]);
|
|
76
|
-
let messageSelected = $state<number>(0);
|
|
77
|
-
|
|
78
|
-
let paginationInfo = new PageInfo();
|
|
79
|
-
|
|
80
|
-
function toggleSideBar(val: MailMenu) {
|
|
81
|
-
const { title } = val;
|
|
82
|
-
if (title === 'Inbox') activeBox = 'inbox';
|
|
83
|
-
else activeBox = 'outbox';
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function setActiveMenu(val: MailMenu): boolean {
|
|
87
|
-
if (activeBox === 'inbox' && val.title === 'Inbox') return true;
|
|
88
|
-
else if (activeBox === 'outbox' && val.title === 'Sent') return true;
|
|
89
|
-
else return false;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
async function fetchData(
|
|
93
|
-
page: number,
|
|
94
|
-
params: TableFilter,
|
|
95
|
-
activeBox: MailingActiveBox = 'inbox'
|
|
96
|
-
) {
|
|
97
|
-
try {
|
|
98
|
-
let currentPage = 0;
|
|
99
|
-
if (params.search) {
|
|
100
|
-
pageInfo.setCurrentPage(1);
|
|
101
|
-
currentPage = pageInfo.currentPage;
|
|
102
|
-
} else {
|
|
103
|
-
currentPage = page || pageInfo.currentPage;
|
|
104
|
-
}
|
|
105
|
-
let newParams: any = {
|
|
106
|
-
page: currentPage,
|
|
107
|
-
pageSize: pageInfo.pageSize,
|
|
108
|
-
search: params.search ?? '',
|
|
109
|
-
filter: params.filter ?? {},
|
|
110
|
-
order: params.order ?? []
|
|
111
|
-
};
|
|
112
|
-
let read = activeBox === activeBox ? readInbox : readOutbox;
|
|
113
|
-
const ret = await read(newParams.page, newParams.pageSize, {
|
|
114
|
-
...params,
|
|
115
|
-
filter: {},
|
|
116
|
-
search: newParams.search ?? ''
|
|
117
|
-
});
|
|
118
|
-
if (!ret?.success) {
|
|
119
|
-
// showError(ret?.message || 'Failed to load data');
|
|
120
|
-
toast.error(ret?.message || 'Failed to load data');
|
|
121
|
-
return true;
|
|
122
|
-
}
|
|
123
|
-
const xs = ret.data;
|
|
124
|
-
// console.log({ xs });
|
|
125
|
-
pageInfo.totalItems = xs.totalCount;
|
|
126
|
-
pageInfo.setHasNextPage(xs.pageInfo.hasNextPage);
|
|
127
|
-
pageInfo.setHasPrevPage(xs.pageInfo.hasPreviousPage);
|
|
128
|
-
// tableData = xs.items;
|
|
129
|
-
messages = xs.items.map((a) => ({ ...a, isChecked: false }));
|
|
130
|
-
} catch (e: any) {
|
|
131
|
-
toast.error(e.message || e);
|
|
132
|
-
} finally {
|
|
133
|
-
busy = false;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function handleRefreshClick() {
|
|
138
|
-
busy = true;
|
|
139
|
-
fetchData(pageNumber, { search: query }, activeBox);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
async function handleArchiveClick() {
|
|
143
|
-
if (selectedMessages.length === 0) return;
|
|
144
|
-
|
|
145
|
-
toast.promise(
|
|
146
|
-
(async () => {
|
|
147
|
-
const results = [];
|
|
148
|
-
|
|
149
|
-
for (const msg of selectedMessages) {
|
|
150
|
-
const res = await toggleArchieve(msg);
|
|
151
|
-
results.push(res);
|
|
152
|
-
}
|
|
153
|
-
selectedMessages = [];
|
|
154
|
-
fetchData(pageNumber, { search: query }, activeBox);
|
|
155
|
-
|
|
156
|
-
return {
|
|
157
|
-
message: `${results.length} message(s) archived successfully`,
|
|
158
|
-
results
|
|
159
|
-
};
|
|
160
|
-
})(),
|
|
161
|
-
{
|
|
162
|
-
loading: `Archiving message(s)...`,
|
|
163
|
-
success: (data: any) => data?.message,
|
|
164
|
-
error: (err: any) => err?.message || 'Failed to archive messages'
|
|
165
|
-
}
|
|
166
|
-
);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
async function handleMarkAsSpam() {
|
|
170
|
-
if (selectedMessages.length === 0) return;
|
|
171
|
-
|
|
172
|
-
toast.promise(
|
|
173
|
-
(async () => {
|
|
174
|
-
const results = [];
|
|
175
|
-
|
|
176
|
-
for (const msg of selectedMessages) {
|
|
177
|
-
const res = await toggleSpam(msg);
|
|
178
|
-
results.push(res);
|
|
179
|
-
}
|
|
180
|
-
selectedMessages = [];
|
|
181
|
-
fetchData(pageNumber, { search: query }, activeBox);
|
|
182
|
-
|
|
183
|
-
return {
|
|
184
|
-
message: `${results.length} message(s) marked as spam successfully`,
|
|
185
|
-
results
|
|
186
|
-
};
|
|
187
|
-
})(),
|
|
188
|
-
{
|
|
189
|
-
loading: `Marking message(s) as spam...`,
|
|
190
|
-
success: (data: any) => data?.message,
|
|
191
|
-
error: (err: any) => err?.message || 'Failed to archive messages'
|
|
192
|
-
}
|
|
193
|
-
);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
async function handleMarkAsRead(val: MailMarkReadToggleType) {
|
|
197
|
-
if (selectedMessages.length === 0) return;
|
|
198
|
-
|
|
199
|
-
toast.promise(
|
|
200
|
-
(async () => {
|
|
201
|
-
const results = [];
|
|
202
|
-
|
|
203
|
-
for (const msg of selectedMessages) {
|
|
204
|
-
const res = await toggleAsRead(msg, val);
|
|
205
|
-
results.push(res);
|
|
206
|
-
}
|
|
207
|
-
selectedMessages = [];
|
|
208
|
-
fetchData(pageNumber, { search: query }, activeBox);
|
|
209
|
-
|
|
210
|
-
return {
|
|
211
|
-
message: `${results.length} message(s) marked as ${val === 'read' ? 'read' : 'unread'} successfully`,
|
|
212
|
-
results
|
|
213
|
-
};
|
|
214
|
-
})(),
|
|
215
|
-
{
|
|
216
|
-
loading: `Marking message(s) as ${val === 'read' ? 'read' : 'unread'}...`,
|
|
217
|
-
success: (data: any) => data?.message,
|
|
218
|
-
error: (err: any) =>
|
|
219
|
-
err?.message || `Failed to ${val === 'read' ? 'read' : 'unread'} messages`
|
|
220
|
-
}
|
|
221
|
-
);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
async function handleMarkAsFavorite(val: MailFavariteToggleType) {
|
|
225
|
-
if (selectedMessages.length === 0) return;
|
|
226
|
-
|
|
227
|
-
toast.promise(
|
|
228
|
-
(async () => {
|
|
229
|
-
const results = [];
|
|
230
|
-
|
|
231
|
-
for (const msg of selectedMessages) {
|
|
232
|
-
const res = await toggleFavourite(msg);
|
|
233
|
-
results.push(res);
|
|
234
|
-
}
|
|
235
|
-
selectedMessages = [];
|
|
236
|
-
fetchData(pageNumber, { search: query }, activeBox);
|
|
237
|
-
|
|
238
|
-
return {
|
|
239
|
-
message: `${results.length} message(s) marked as ${val === 'favorite' ? 'favorite' : 'unfavorite'} successfully`,
|
|
240
|
-
results
|
|
241
|
-
};
|
|
242
|
-
})(),
|
|
243
|
-
{
|
|
244
|
-
loading: `Marking message(s) as ${val === 'favorite' ? 'favorite' : 'unfavorite'}...`,
|
|
245
|
-
success: (data: any) => data?.message,
|
|
246
|
-
error: (err: any) =>
|
|
247
|
-
err?.message || `Failed to ${val === 'favorite' ? 'favorite' : 'unfavorite'} messages`
|
|
248
|
-
}
|
|
249
|
-
);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
async function handleMarkAsImportant(val: 'isImportant' | 'notImportant') {
|
|
253
|
-
if (selectedMessages.length === 0) return;
|
|
254
|
-
|
|
255
|
-
toast.promise(
|
|
256
|
-
(async () => {
|
|
257
|
-
const results = [];
|
|
258
|
-
|
|
259
|
-
for (const msg of selectedMessages) {
|
|
260
|
-
const res = await toggelImportant(msg);
|
|
261
|
-
results.push(res);
|
|
262
|
-
}
|
|
263
|
-
selectedMessages = [];
|
|
264
|
-
fetchData(pageNumber, { search: query }, activeBox);
|
|
265
|
-
|
|
266
|
-
return {
|
|
267
|
-
message: `${results.length} message(s) marked as ${val === 'isImportant' ? 'important' : 'not important'} successfully`,
|
|
268
|
-
results
|
|
269
|
-
};
|
|
270
|
-
})(),
|
|
271
|
-
{
|
|
272
|
-
loading: `Marking message(s) as ${val === 'isImportant' ? 'important' : 'not important'}...`,
|
|
273
|
-
success: (data: any) => data?.message,
|
|
274
|
-
error: (err: any) =>
|
|
275
|
-
err?.message ||
|
|
276
|
-
`Failed to ${val === 'isImportant' ? 'important' : 'not important'} messages`
|
|
277
|
-
}
|
|
278
|
-
);
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
async function handleDeleteMessages() {
|
|
282
|
-
if (selectedMessages.length === 0) return;
|
|
283
|
-
|
|
284
|
-
toast.promise(
|
|
285
|
-
(async () => {
|
|
286
|
-
const results = [];
|
|
287
|
-
|
|
288
|
-
for (const msg of selectedMessages) {
|
|
289
|
-
const res = await deleteEntry(msg);
|
|
290
|
-
results.push(res);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
openDeleteAlert = false;
|
|
294
|
-
selectedMessages = [];
|
|
295
|
-
fetchData(pageNumber, { search: query }, activeBox);
|
|
296
|
-
|
|
297
|
-
return {
|
|
298
|
-
message: `${results.length} message(s) deleted successfully`,
|
|
299
|
-
results
|
|
300
|
-
};
|
|
301
|
-
})(),
|
|
302
|
-
{
|
|
303
|
-
loading: `Deleting message(s)...`,
|
|
304
|
-
success: (data: any) => data?.message,
|
|
305
|
-
error: (err: any) => err?.message || 'Failed to delete messages'
|
|
306
|
-
}
|
|
307
|
-
);
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
function handleItemChecked({ checked, id }: any) {
|
|
311
|
-
if (checked) {
|
|
312
|
-
selectedMessages = [...selectedMessages, id];
|
|
313
|
-
} else {
|
|
314
|
-
selectedMessages = selectedMessages.filter((a) => a !== id);
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
function handleMessageSelected(id: number) {
|
|
319
|
-
messageSelected = id;
|
|
320
|
-
selectedMessages = [id];
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
function updatePageInfo(val: MailPageInfo) {
|
|
324
|
-
// console.log({ val });
|
|
325
|
-
paginationInfo.totalItems = 1;
|
|
326
|
-
paginationInfo.setHasNextPage(val.hasNextPage);
|
|
327
|
-
paginationInfo.setHasPrevPage(val.hasPreviousPage);
|
|
328
|
-
paginationInfo.setTotalPages(1);
|
|
329
|
-
paginationInfo.setPageSize(1);
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
const debouncedSearch = debounce(fetchData, 300);
|
|
333
|
-
|
|
334
|
-
function handleSearch(val: string) {
|
|
335
|
-
// query = val;
|
|
336
|
-
debouncedSearch(pageNumber, { search: val }, activeBox);
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
async function getIsRead(id: number): Promise<boolean> {
|
|
340
|
-
let status = false;
|
|
341
|
-
try {
|
|
342
|
-
const ret = await readAMessage(id);
|
|
343
|
-
if (!ret?.success) {
|
|
344
|
-
return false;
|
|
345
|
-
}
|
|
346
|
-
status = ret.data?.isRead || false;
|
|
347
|
-
return status;
|
|
348
|
-
} catch (error) {}
|
|
349
|
-
return status;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
$effect(() => {
|
|
353
|
-
fetchData(pageNumber, { search: query }, activeBox);
|
|
354
|
-
});
|
|
355
|
-
</script>
|
|
356
|
-
|
|
357
|
-
<div class="h-full w-full">
|
|
358
|
-
<div class="flex h-full w-full gap-2">
|
|
359
|
-
<div class:hidden={!showSidePanel} class="loginbox h-full w-20 rounded-md bg-white">
|
|
360
|
-
<MailSidebar onClick={toggleSideBar} menus={menutItems} {setActiveMenu} />
|
|
361
|
-
</div>
|
|
362
|
-
<div class="flex w-full flex-grow flex-col gap-1">
|
|
363
|
-
<div class="loginbox h-14 rounded bg-white px-4">
|
|
364
|
-
<MailToolBar
|
|
365
|
-
isFavoriteActive={false}
|
|
366
|
-
isReadActive={async () => await getIsRead(messageSelected)}
|
|
367
|
-
showBackButton={Boolean(messageSelected)}
|
|
368
|
-
{showPagination}
|
|
369
|
-
{showComposeButton}
|
|
370
|
-
{showSearch}
|
|
371
|
-
{showArchiveButton}
|
|
372
|
-
{showDeleteButton}
|
|
373
|
-
{showMarkReadButton}
|
|
374
|
-
{showFavoriteButton}
|
|
375
|
-
{showMarkAsSpamButton}
|
|
376
|
-
{customFilterComponent}
|
|
377
|
-
onRefreshClick={handleRefreshClick}
|
|
378
|
-
onArchiveClick={handleArchiveClick}
|
|
379
|
-
onMarkAsSpamClick={handleMarkAsSpam}
|
|
380
|
-
onToggleMarkReadClick={handleMarkAsRead}
|
|
381
|
-
onToggleFavoriteClick={handleMarkAsFavorite}
|
|
382
|
-
onsearchChange={handleSearch}
|
|
383
|
-
onBackClick={() => {
|
|
384
|
-
messageSelected = 0;
|
|
385
|
-
selectedMessages = [];
|
|
386
|
-
}}
|
|
387
|
-
onDeleteClick={() => {
|
|
388
|
-
if (selectedMessages.length === 0) return;
|
|
389
|
-
openDeleteAlert = true;
|
|
390
|
-
}}
|
|
391
|
-
selectedMails={selectedMessages}
|
|
392
|
-
pageInfo={{
|
|
393
|
-
currentPage: !messageSelected ? pageInfo.currentPage : paginationInfo.currentPage,
|
|
394
|
-
pageSize: !messageSelected ? pageInfo.pageSize : paginationInfo.pageSize,
|
|
395
|
-
totalCount: !messageSelected ? pageInfo.totalItems : paginationInfo.totalItems,
|
|
396
|
-
hasNextPage: !messageSelected ? pageInfo.hasNextPage : paginationInfo.hasNextPage,
|
|
397
|
-
hasPreviousPage: !messageSelected ? pageInfo.hasPrevPage : paginationInfo.hasPrevPage
|
|
398
|
-
}}
|
|
399
|
-
/>
|
|
400
|
-
</div>
|
|
401
|
-
|
|
402
|
-
<div class="loginbox h-full w-full flex-grow rounded bg-gray-100 p-2">
|
|
403
|
-
{#if busy}
|
|
404
|
-
<PageLoader size={50} />
|
|
405
|
-
{:else if messageSelected}
|
|
406
|
-
<MailingMessageViewer
|
|
407
|
-
bind:recordId={messageSelected}
|
|
408
|
-
readMessage={readAMessage}
|
|
409
|
-
{updatePageInfo}
|
|
410
|
-
{showReplies}
|
|
411
|
-
showHeader={activeBox === 'inbox'}
|
|
412
|
-
/>
|
|
413
|
-
{:else if messages.length}
|
|
414
|
-
<div class="custom-scrollbar h-full w-full overflow-auto" in:slide>
|
|
415
|
-
{#each messages as message}
|
|
416
|
-
<MailingMessageCard
|
|
417
|
-
{...message}
|
|
418
|
-
onItemChecked={handleItemChecked}
|
|
419
|
-
showMarkAsFavorite={showFavoriteButton}
|
|
420
|
-
showMarkAsImportant={showMarkAsImportantButton}
|
|
421
|
-
toggleFavorited={() => {
|
|
422
|
-
selectedMessages = [message.id];
|
|
423
|
-
handleMarkAsFavorite(message.isStared ? 'unfavorite' : 'favorite');
|
|
424
|
-
}}
|
|
425
|
-
toggelImportant={() => {
|
|
426
|
-
selectedMessages = [message.id];
|
|
427
|
-
handleMarkAsImportant(message.isImportant ? 'notImportant' : 'isImportant');
|
|
428
|
-
}}
|
|
429
|
-
onItemSelected={handleMessageSelected}
|
|
430
|
-
/>
|
|
431
|
-
{/each}
|
|
432
|
-
</div>
|
|
433
|
-
{:else}
|
|
434
|
-
<div class="grid h-full w-full items-center justify-center p-20" in:scale>
|
|
435
|
-
<div class="rounded-[5px] bg-yellow-300 px-10 py-5 text-center">No Records Found</div>
|
|
436
|
-
</div>
|
|
437
|
-
{/if}
|
|
438
|
-
</div>
|
|
439
|
-
</div>
|
|
440
|
-
</div>
|
|
441
|
-
</div>
|
|
442
|
-
|
|
443
|
-
<AlertDialog
|
|
444
|
-
open={openDeleteAlert}
|
|
445
|
-
message={`Are you sure you want to delete ${selectedMessages?.length > 1 ? 'these messages' : 'this message'}`}
|
|
446
|
-
onCancel={() => (openDeleteAlert = false)}
|
|
447
|
-
onYes={handleDeleteMessages}
|
|
448
|
-
/>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { PageLoader } from '../../ui/pageLoader/index.js';
|
|
3
|
+
import { scale, slide } from 'svelte/transition';
|
|
4
|
+
import {
|
|
5
|
+
MailSidebar,
|
|
6
|
+
MailToolBar,
|
|
7
|
+
type MailingModuleProps,
|
|
8
|
+
type MailMenu,
|
|
9
|
+
type MailingMessage,
|
|
10
|
+
type MailMarkReadToggleType,
|
|
11
|
+
type MailFavariteToggleType,
|
|
12
|
+
type MailPageInfo,
|
|
13
|
+
type MailingActiveBox
|
|
14
|
+
} from './index.js';
|
|
15
|
+
import MailingMessageCard from './MailingMessageCard.svelte';
|
|
16
|
+
import { toast, type CrudResult, type TableFilter } from '../../index.js';
|
|
17
|
+
import { PageInfo } from '../../utils/paginate.svelte.js';
|
|
18
|
+
import AlertDialog from '../../ui/alertDialog/AlertDialog.svelte';
|
|
19
|
+
import MailingMessageViewer from './MailingMessageViewer.svelte';
|
|
20
|
+
import debounce from 'lodash/debounce';
|
|
21
|
+
|
|
22
|
+
let {
|
|
23
|
+
showSidePanel = true,
|
|
24
|
+
showPagination = true,
|
|
25
|
+
showComposeButton = true,
|
|
26
|
+
showSearch = true,
|
|
27
|
+
customFilterComponent,
|
|
28
|
+
showArchiveButton = true,
|
|
29
|
+
showDeleteButton = true,
|
|
30
|
+
showMarkReadButton = true,
|
|
31
|
+
showFavoriteButton = true,
|
|
32
|
+
showMarkAsSpamButton = true,
|
|
33
|
+
showReplies = true,
|
|
34
|
+
showMarkAsImportantButton = true,
|
|
35
|
+
readInbox = $bindable((skip?: number, take?: number, filter?: TableFilter<any>) => {
|
|
36
|
+
return null;
|
|
37
|
+
}),
|
|
38
|
+
readOutbox = $bindable((skip?: number, take?: number, filter?: TableFilter<any>) => {
|
|
39
|
+
return null;
|
|
40
|
+
}),
|
|
41
|
+
deleteEntry = async (id: string | number) => {
|
|
42
|
+
return { success: false, data: null, error: null } as any;
|
|
43
|
+
},
|
|
44
|
+
toggleArchieve = async (id: string | number) => {
|
|
45
|
+
return { success: false, data: null, error: null } as any;
|
|
46
|
+
},
|
|
47
|
+
toggleAsRead = async (id: string | number, type?: MailMarkReadToggleType) => {
|
|
48
|
+
return { success: false, data: null, error: null } as any;
|
|
49
|
+
},
|
|
50
|
+
toggleFavourite = async (id: string | number) => {
|
|
51
|
+
return { success: false, data: null, error: null } as any;
|
|
52
|
+
},
|
|
53
|
+
toggleSpam = async (id: string | number) => {
|
|
54
|
+
return { success: false, data: null, error: null } as any;
|
|
55
|
+
},
|
|
56
|
+
toggelImportant = async (id: string | number) => {
|
|
57
|
+
return { success: false, data: null, error: null } as any;
|
|
58
|
+
},
|
|
59
|
+
readAMessage = async (id: string | number) => {
|
|
60
|
+
return { success: false, data: null, error: null } as any;
|
|
61
|
+
}
|
|
62
|
+
}: MailingModuleProps = $props();
|
|
63
|
+
|
|
64
|
+
let activeBox = $state<MailingActiveBox>('inbox');
|
|
65
|
+
let pageInfo = new PageInfo();
|
|
66
|
+
let menutItems = $state([
|
|
67
|
+
{ icon: 'bx:bxs-inbox', title: 'Inbox', count: 0, path: '' },
|
|
68
|
+
{ icon: 'bx:bxs-send', title: 'Sent', count: 0, path: '' }
|
|
69
|
+
]);
|
|
70
|
+
let openDeleteAlert = $state(false);
|
|
71
|
+
let busy = $state(true);
|
|
72
|
+
let messages = $state<MailingMessage[]>([]);
|
|
73
|
+
let pageNumber = $derived(pageInfo.currentPage);
|
|
74
|
+
let query = $state('');
|
|
75
|
+
let selectedMessages = $state<number[]>([]);
|
|
76
|
+
let messageSelected = $state<number>(0);
|
|
77
|
+
|
|
78
|
+
let paginationInfo = new PageInfo();
|
|
79
|
+
|
|
80
|
+
function toggleSideBar(val: MailMenu) {
|
|
81
|
+
const { title } = val;
|
|
82
|
+
if (title === 'Inbox') activeBox = 'inbox';
|
|
83
|
+
else activeBox = 'outbox';
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function setActiveMenu(val: MailMenu): boolean {
|
|
87
|
+
if (activeBox === 'inbox' && val.title === 'Inbox') return true;
|
|
88
|
+
else if (activeBox === 'outbox' && val.title === 'Sent') return true;
|
|
89
|
+
else return false;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function fetchData(
|
|
93
|
+
page: number,
|
|
94
|
+
params: TableFilter,
|
|
95
|
+
activeBox: MailingActiveBox = 'inbox'
|
|
96
|
+
) {
|
|
97
|
+
try {
|
|
98
|
+
let currentPage = 0;
|
|
99
|
+
if (params.search) {
|
|
100
|
+
pageInfo.setCurrentPage(1);
|
|
101
|
+
currentPage = pageInfo.currentPage;
|
|
102
|
+
} else {
|
|
103
|
+
currentPage = page || pageInfo.currentPage;
|
|
104
|
+
}
|
|
105
|
+
let newParams: any = {
|
|
106
|
+
page: currentPage,
|
|
107
|
+
pageSize: pageInfo.pageSize,
|
|
108
|
+
search: params.search ?? '',
|
|
109
|
+
filter: params.filter ?? {},
|
|
110
|
+
order: params.order ?? []
|
|
111
|
+
};
|
|
112
|
+
let read = activeBox === activeBox ? readInbox : readOutbox;
|
|
113
|
+
const ret = await read(newParams.page, newParams.pageSize, {
|
|
114
|
+
...params,
|
|
115
|
+
filter: {},
|
|
116
|
+
search: newParams.search ?? ''
|
|
117
|
+
});
|
|
118
|
+
if (!ret?.success) {
|
|
119
|
+
// showError(ret?.message || 'Failed to load data');
|
|
120
|
+
toast.error(ret?.message || 'Failed to load data');
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
const xs = ret.data;
|
|
124
|
+
// console.log({ xs });
|
|
125
|
+
pageInfo.totalItems = xs.totalCount;
|
|
126
|
+
pageInfo.setHasNextPage(xs.pageInfo.hasNextPage);
|
|
127
|
+
pageInfo.setHasPrevPage(xs.pageInfo.hasPreviousPage);
|
|
128
|
+
// tableData = xs.items;
|
|
129
|
+
messages = xs.items.map((a) => ({ ...a, isChecked: false }));
|
|
130
|
+
} catch (e: any) {
|
|
131
|
+
toast.error(e.message || e);
|
|
132
|
+
} finally {
|
|
133
|
+
busy = false;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function handleRefreshClick() {
|
|
138
|
+
busy = true;
|
|
139
|
+
fetchData(pageNumber, { search: query }, activeBox);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
async function handleArchiveClick() {
|
|
143
|
+
if (selectedMessages.length === 0) return;
|
|
144
|
+
|
|
145
|
+
toast.promise(
|
|
146
|
+
(async () => {
|
|
147
|
+
const results = [];
|
|
148
|
+
|
|
149
|
+
for (const msg of selectedMessages) {
|
|
150
|
+
const res = await toggleArchieve(msg);
|
|
151
|
+
results.push(res);
|
|
152
|
+
}
|
|
153
|
+
selectedMessages = [];
|
|
154
|
+
fetchData(pageNumber, { search: query }, activeBox);
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
message: `${results.length} message(s) archived successfully`,
|
|
158
|
+
results
|
|
159
|
+
};
|
|
160
|
+
})(),
|
|
161
|
+
{
|
|
162
|
+
loading: `Archiving message(s)...`,
|
|
163
|
+
success: (data: any) => data?.message,
|
|
164
|
+
error: (err: any) => err?.message || 'Failed to archive messages'
|
|
165
|
+
}
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async function handleMarkAsSpam() {
|
|
170
|
+
if (selectedMessages.length === 0) return;
|
|
171
|
+
|
|
172
|
+
toast.promise(
|
|
173
|
+
(async () => {
|
|
174
|
+
const results = [];
|
|
175
|
+
|
|
176
|
+
for (const msg of selectedMessages) {
|
|
177
|
+
const res = await toggleSpam(msg);
|
|
178
|
+
results.push(res);
|
|
179
|
+
}
|
|
180
|
+
selectedMessages = [];
|
|
181
|
+
fetchData(pageNumber, { search: query }, activeBox);
|
|
182
|
+
|
|
183
|
+
return {
|
|
184
|
+
message: `${results.length} message(s) marked as spam successfully`,
|
|
185
|
+
results
|
|
186
|
+
};
|
|
187
|
+
})(),
|
|
188
|
+
{
|
|
189
|
+
loading: `Marking message(s) as spam...`,
|
|
190
|
+
success: (data: any) => data?.message,
|
|
191
|
+
error: (err: any) => err?.message || 'Failed to archive messages'
|
|
192
|
+
}
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
async function handleMarkAsRead(val: MailMarkReadToggleType) {
|
|
197
|
+
if (selectedMessages.length === 0) return;
|
|
198
|
+
|
|
199
|
+
toast.promise(
|
|
200
|
+
(async () => {
|
|
201
|
+
const results = [];
|
|
202
|
+
|
|
203
|
+
for (const msg of selectedMessages) {
|
|
204
|
+
const res = await toggleAsRead(msg, val);
|
|
205
|
+
results.push(res);
|
|
206
|
+
}
|
|
207
|
+
selectedMessages = [];
|
|
208
|
+
fetchData(pageNumber, { search: query }, activeBox);
|
|
209
|
+
|
|
210
|
+
return {
|
|
211
|
+
message: `${results.length} message(s) marked as ${val === 'read' ? 'read' : 'unread'} successfully`,
|
|
212
|
+
results
|
|
213
|
+
};
|
|
214
|
+
})(),
|
|
215
|
+
{
|
|
216
|
+
loading: `Marking message(s) as ${val === 'read' ? 'read' : 'unread'}...`,
|
|
217
|
+
success: (data: any) => data?.message,
|
|
218
|
+
error: (err: any) =>
|
|
219
|
+
err?.message || `Failed to ${val === 'read' ? 'read' : 'unread'} messages`
|
|
220
|
+
}
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
async function handleMarkAsFavorite(val: MailFavariteToggleType) {
|
|
225
|
+
if (selectedMessages.length === 0) return;
|
|
226
|
+
|
|
227
|
+
toast.promise(
|
|
228
|
+
(async () => {
|
|
229
|
+
const results = [];
|
|
230
|
+
|
|
231
|
+
for (const msg of selectedMessages) {
|
|
232
|
+
const res = await toggleFavourite(msg);
|
|
233
|
+
results.push(res);
|
|
234
|
+
}
|
|
235
|
+
selectedMessages = [];
|
|
236
|
+
fetchData(pageNumber, { search: query }, activeBox);
|
|
237
|
+
|
|
238
|
+
return {
|
|
239
|
+
message: `${results.length} message(s) marked as ${val === 'favorite' ? 'favorite' : 'unfavorite'} successfully`,
|
|
240
|
+
results
|
|
241
|
+
};
|
|
242
|
+
})(),
|
|
243
|
+
{
|
|
244
|
+
loading: `Marking message(s) as ${val === 'favorite' ? 'favorite' : 'unfavorite'}...`,
|
|
245
|
+
success: (data: any) => data?.message,
|
|
246
|
+
error: (err: any) =>
|
|
247
|
+
err?.message || `Failed to ${val === 'favorite' ? 'favorite' : 'unfavorite'} messages`
|
|
248
|
+
}
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
async function handleMarkAsImportant(val: 'isImportant' | 'notImportant') {
|
|
253
|
+
if (selectedMessages.length === 0) return;
|
|
254
|
+
|
|
255
|
+
toast.promise(
|
|
256
|
+
(async () => {
|
|
257
|
+
const results = [];
|
|
258
|
+
|
|
259
|
+
for (const msg of selectedMessages) {
|
|
260
|
+
const res = await toggelImportant(msg);
|
|
261
|
+
results.push(res);
|
|
262
|
+
}
|
|
263
|
+
selectedMessages = [];
|
|
264
|
+
fetchData(pageNumber, { search: query }, activeBox);
|
|
265
|
+
|
|
266
|
+
return {
|
|
267
|
+
message: `${results.length} message(s) marked as ${val === 'isImportant' ? 'important' : 'not important'} successfully`,
|
|
268
|
+
results
|
|
269
|
+
};
|
|
270
|
+
})(),
|
|
271
|
+
{
|
|
272
|
+
loading: `Marking message(s) as ${val === 'isImportant' ? 'important' : 'not important'}...`,
|
|
273
|
+
success: (data: any) => data?.message,
|
|
274
|
+
error: (err: any) =>
|
|
275
|
+
err?.message ||
|
|
276
|
+
`Failed to ${val === 'isImportant' ? 'important' : 'not important'} messages`
|
|
277
|
+
}
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
async function handleDeleteMessages() {
|
|
282
|
+
if (selectedMessages.length === 0) return;
|
|
283
|
+
|
|
284
|
+
toast.promise(
|
|
285
|
+
(async () => {
|
|
286
|
+
const results = [];
|
|
287
|
+
|
|
288
|
+
for (const msg of selectedMessages) {
|
|
289
|
+
const res = await deleteEntry(msg);
|
|
290
|
+
results.push(res);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
openDeleteAlert = false;
|
|
294
|
+
selectedMessages = [];
|
|
295
|
+
fetchData(pageNumber, { search: query }, activeBox);
|
|
296
|
+
|
|
297
|
+
return {
|
|
298
|
+
message: `${results.length} message(s) deleted successfully`,
|
|
299
|
+
results
|
|
300
|
+
};
|
|
301
|
+
})(),
|
|
302
|
+
{
|
|
303
|
+
loading: `Deleting message(s)...`,
|
|
304
|
+
success: (data: any) => data?.message,
|
|
305
|
+
error: (err: any) => err?.message || 'Failed to delete messages'
|
|
306
|
+
}
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
function handleItemChecked({ checked, id }: any) {
|
|
311
|
+
if (checked) {
|
|
312
|
+
selectedMessages = [...selectedMessages, id];
|
|
313
|
+
} else {
|
|
314
|
+
selectedMessages = selectedMessages.filter((a) => a !== id);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
function handleMessageSelected(id: number) {
|
|
319
|
+
messageSelected = id;
|
|
320
|
+
selectedMessages = [id];
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
function updatePageInfo(val: MailPageInfo) {
|
|
324
|
+
// console.log({ val });
|
|
325
|
+
paginationInfo.totalItems = 1;
|
|
326
|
+
paginationInfo.setHasNextPage(val.hasNextPage);
|
|
327
|
+
paginationInfo.setHasPrevPage(val.hasPreviousPage);
|
|
328
|
+
paginationInfo.setTotalPages(1);
|
|
329
|
+
paginationInfo.setPageSize(1);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
const debouncedSearch = debounce(fetchData, 300);
|
|
333
|
+
|
|
334
|
+
function handleSearch(val: string) {
|
|
335
|
+
// query = val;
|
|
336
|
+
debouncedSearch(pageNumber, { search: val }, activeBox);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
async function getIsRead(id: number): Promise<boolean> {
|
|
340
|
+
let status = false;
|
|
341
|
+
try {
|
|
342
|
+
const ret = await readAMessage(id);
|
|
343
|
+
if (!ret?.success) {
|
|
344
|
+
return false;
|
|
345
|
+
}
|
|
346
|
+
status = ret.data?.isRead || false;
|
|
347
|
+
return status;
|
|
348
|
+
} catch (error) {}
|
|
349
|
+
return status;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
$effect(() => {
|
|
353
|
+
fetchData(pageNumber, { search: query }, activeBox);
|
|
354
|
+
});
|
|
355
|
+
</script>
|
|
356
|
+
|
|
357
|
+
<div class="h-full w-full">
|
|
358
|
+
<div class="flex h-full w-full gap-2">
|
|
359
|
+
<div class:hidden={!showSidePanel} class="loginbox h-full w-20 rounded-md bg-white">
|
|
360
|
+
<MailSidebar onClick={toggleSideBar} menus={menutItems} {setActiveMenu} />
|
|
361
|
+
</div>
|
|
362
|
+
<div class="flex w-full flex-grow flex-col gap-1">
|
|
363
|
+
<div class="loginbox h-14 rounded bg-white px-4">
|
|
364
|
+
<MailToolBar
|
|
365
|
+
isFavoriteActive={false}
|
|
366
|
+
isReadActive={async () => await getIsRead(messageSelected)}
|
|
367
|
+
showBackButton={Boolean(messageSelected)}
|
|
368
|
+
{showPagination}
|
|
369
|
+
{showComposeButton}
|
|
370
|
+
{showSearch}
|
|
371
|
+
{showArchiveButton}
|
|
372
|
+
{showDeleteButton}
|
|
373
|
+
{showMarkReadButton}
|
|
374
|
+
{showFavoriteButton}
|
|
375
|
+
{showMarkAsSpamButton}
|
|
376
|
+
{customFilterComponent}
|
|
377
|
+
onRefreshClick={handleRefreshClick}
|
|
378
|
+
onArchiveClick={handleArchiveClick}
|
|
379
|
+
onMarkAsSpamClick={handleMarkAsSpam}
|
|
380
|
+
onToggleMarkReadClick={handleMarkAsRead}
|
|
381
|
+
onToggleFavoriteClick={handleMarkAsFavorite}
|
|
382
|
+
onsearchChange={handleSearch}
|
|
383
|
+
onBackClick={() => {
|
|
384
|
+
messageSelected = 0;
|
|
385
|
+
selectedMessages = [];
|
|
386
|
+
}}
|
|
387
|
+
onDeleteClick={() => {
|
|
388
|
+
if (selectedMessages.length === 0) return;
|
|
389
|
+
openDeleteAlert = true;
|
|
390
|
+
}}
|
|
391
|
+
selectedMails={selectedMessages}
|
|
392
|
+
pageInfo={{
|
|
393
|
+
currentPage: !messageSelected ? pageInfo.currentPage : paginationInfo.currentPage,
|
|
394
|
+
pageSize: !messageSelected ? pageInfo.pageSize : paginationInfo.pageSize,
|
|
395
|
+
totalCount: !messageSelected ? pageInfo.totalItems : paginationInfo.totalItems,
|
|
396
|
+
hasNextPage: !messageSelected ? pageInfo.hasNextPage : paginationInfo.hasNextPage,
|
|
397
|
+
hasPreviousPage: !messageSelected ? pageInfo.hasPrevPage : paginationInfo.hasPrevPage
|
|
398
|
+
}}
|
|
399
|
+
/>
|
|
400
|
+
</div>
|
|
401
|
+
|
|
402
|
+
<div class="loginbox h-full w-full flex-grow rounded bg-gray-100 p-2">
|
|
403
|
+
{#if busy}
|
|
404
|
+
<PageLoader size={50} />
|
|
405
|
+
{:else if messageSelected}
|
|
406
|
+
<MailingMessageViewer
|
|
407
|
+
bind:recordId={messageSelected}
|
|
408
|
+
readMessage={readAMessage}
|
|
409
|
+
{updatePageInfo}
|
|
410
|
+
{showReplies}
|
|
411
|
+
showHeader={activeBox === 'inbox'}
|
|
412
|
+
/>
|
|
413
|
+
{:else if messages.length}
|
|
414
|
+
<div class="custom-scrollbar h-full w-full overflow-auto" in:slide>
|
|
415
|
+
{#each messages as message}
|
|
416
|
+
<MailingMessageCard
|
|
417
|
+
{...message}
|
|
418
|
+
onItemChecked={handleItemChecked}
|
|
419
|
+
showMarkAsFavorite={showFavoriteButton}
|
|
420
|
+
showMarkAsImportant={showMarkAsImportantButton}
|
|
421
|
+
toggleFavorited={() => {
|
|
422
|
+
selectedMessages = [message.id];
|
|
423
|
+
handleMarkAsFavorite(message.isStared ? 'unfavorite' : 'favorite');
|
|
424
|
+
}}
|
|
425
|
+
toggelImportant={() => {
|
|
426
|
+
selectedMessages = [message.id];
|
|
427
|
+
handleMarkAsImportant(message.isImportant ? 'notImportant' : 'isImportant');
|
|
428
|
+
}}
|
|
429
|
+
onItemSelected={handleMessageSelected}
|
|
430
|
+
/>
|
|
431
|
+
{/each}
|
|
432
|
+
</div>
|
|
433
|
+
{:else}
|
|
434
|
+
<div class="grid h-full w-full items-center justify-center p-20" in:scale>
|
|
435
|
+
<div class="rounded-[5px] bg-yellow-300 px-10 py-5 text-center">No Records Found</div>
|
|
436
|
+
</div>
|
|
437
|
+
{/if}
|
|
438
|
+
</div>
|
|
439
|
+
</div>
|
|
440
|
+
</div>
|
|
441
|
+
</div>
|
|
442
|
+
|
|
443
|
+
<AlertDialog
|
|
444
|
+
open={openDeleteAlert}
|
|
445
|
+
message={`Are you sure you want to delete ${selectedMessages?.length > 1 ? 'these messages' : 'this message'}`}
|
|
446
|
+
onCancel={() => (openDeleteAlert = false)}
|
|
447
|
+
onYes={handleDeleteMessages}
|
|
448
|
+
/>
|