Skip to content

Commit e313d7f

Browse files
committed
fix: move getList() and startBulkAction() functions from listView to utils
1 parent f48a6ca commit e313d7f

File tree

2 files changed

+112
-90
lines changed

2 files changed

+112
-90
lines changed

adminforth/spa/src/utils.ts

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { onMounted, ref, resolveComponent } from 'vue';
1+
import { nextTick, onMounted, ref, resolveComponent } from 'vue';
22
import type { CoreConfig } from './spa_types/core';
33
import type { ValidationObject } from './types/Common.js';
44
import router from "./router";
@@ -11,6 +11,11 @@ import debounce from 'debounce';
1111
import type { AdminForthResourceColumnInputCommon, Predicate } from '@/types/Common';
1212
import { i18nInstance } from './i18n'
1313

14+
import { type AdminForthResourceCommon } from './types/Common';
15+
import { useAdminforth } from '@/adminforth';
16+
import { showErrorTost } from '@/composables/useFrontendApi'
17+
18+
1419
const LS_LANG_KEY = `afLanguage`;
1520
const MAX_CONSECUTIVE_EMPTY_RESULTS = 2;
1621
const ITEMS_PER_PAGE_LIMIT = 100;
@@ -513,4 +518,89 @@ export function btoa_function(source: string): string {
513518

514519
export function atob_function(source: string): string {
515520
return atob(source);
521+
}
522+
523+
524+
export async function getList(resource: AdminForthResourceCommon, isPageLoaded: boolean, page: number | null , pageSize: number, sort: any, checkboxes:{ value: any[] }, filters: any = [] ) {
525+
let rows: any[] = [];
526+
let totalRows: number | null = null;
527+
if (!isPageLoaded) {
528+
return;
529+
}
530+
const data = await callAdminForthApi({
531+
path: '/get_resource_data',
532+
method: 'POST',
533+
body: {
534+
source: 'list',
535+
resourceId: resource.resourceId,
536+
limit: pageSize,
537+
offset: ((page || 1) - 1) * pageSize,
538+
filters: filters,
539+
sort: sort,
540+
}
541+
});
542+
if (data.error) {
543+
showErrorTost(data.error);
544+
rows = [];
545+
totalRows = 0;
546+
return {rows, totalRows, error: data.error};
547+
}
548+
rows = data.data?.map((row: any) => {
549+
if (resource?.columns?.find(c => c.primaryKey)?.foreignResource) {
550+
row._primaryKeyValue = row[resource.columns.find(c => c.primaryKey)!.name].pk;
551+
} else if (resource) {
552+
row._primaryKeyValue = row[resource.columns.find(c => c.primaryKey)!.name];
553+
}
554+
return row;
555+
});
556+
totalRows = data.total;
557+
558+
// if checkboxes have items which are not in current data, remove them
559+
checkboxes.value = checkboxes.value.filter((pk: any) => rows.some((r: any) => r._primaryKeyValue === pk));
560+
await nextTick();
561+
return { rows, totalRows };
562+
}
563+
564+
565+
566+
export async function startBulkAction(actionId: string, resource: AdminForthResourceCommon, checkboxes: { value: string[] },
567+
bulkActionLoadingStates: {value: Record<string, boolean>}, getListInner: Function) {
568+
const action = resource?.options?.bulkActions?.find(a => a.id === actionId);
569+
const { confirm, alert } = useAdminforth();
570+
571+
if (action?.confirm) {
572+
const confirmed = await confirm({
573+
message: action.confirm,
574+
});
575+
if (!confirmed) {
576+
return;
577+
}
578+
}
579+
bulkActionLoadingStates.value[actionId] = true;
580+
581+
const data = await callAdminForthApi({
582+
path: '/start_bulk_action',
583+
method: 'POST',
584+
body: {
585+
resourceId: resource.resourceId,
586+
actionId: actionId,
587+
recordIds: checkboxes.value
588+
}
589+
});
590+
bulkActionLoadingStates.value[actionId] = false;
591+
if (data?.ok) {
592+
checkboxes.value = [];
593+
await getListInner();
594+
595+
if (data.successMessage) {
596+
alert({
597+
message: data.successMessage,
598+
variant: 'success'
599+
});
600+
}
601+
602+
}
603+
if (data?.error) {
604+
showErrorTost(data.error);
605+
}
516606
}

adminforth/spa/src/views/ListView.vue

Lines changed: 21 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
<button
4949
v-if="!action.showInThreeDotsDropdown"
5050
:key="action.id"
51-
@click="startBulkAction(action.id!)"
51+
@click="startBulkActionInner(action.id!)"
5252
class="flex gap-1 items-center py-1 px-3 text-sm font-medium text-lightListViewButtonText focus:outline-none bg-lightListViewButtonBackground rounded-default border border-lightListViewButtonBorder hover:bg-lightListViewButtonBackgroundHover hover:text-lightListViewButtonTextHover focus:z-10 focus:ring-4 focus:ring-lightListViewButtonFocusRing dark:focus:ring-darkListViewButtonFocusRing dark:bg-darkListViewButtonBackground dark:text-darkListViewButtonText dark:border-darkListViewButtonBorder dark:hover:text-darkListViewButtonTextHover dark:hover:bg-darkListViewButtonBackgroundHover"
5353
:class="action.buttonCustomCssClass || ''"
5454
>
@@ -104,8 +104,8 @@
104104
:threeDotsDropdownItems="(coreStore.resourceOptions?.pageInjections?.list?.threeDotsDropdownItems as [])"
105105
:bulkActions="coreStore.resource?.options?.bulkActions"
106106
:checkboxes="checkboxes"
107-
@startBulkAction="startBulkAction"
108-
:updateList="getList"
107+
@startBulkAction="startBulkActionInner"
108+
:updateList="getListInner"
109109
:clearCheckboxes="clearCheckboxes"
110110
></ThreeDotsMenu>
111111
</BreadcrumbsWithButtons>
@@ -126,7 +126,7 @@
126126
@update:page="page = $event"
127127
@update:sort="sort = $event"
128128
@update:checkboxes="checkboxes = $event"
129-
@update:records="getList"
129+
@update:records="getListInner"
130130
:sort="sort"
131131
:pageSize="pageSize"
132132
:totalRows="totalRows"
@@ -164,7 +164,7 @@
164164
@update:page="page = $event"
165165
@update:sort="sort = $event"
166166
@update:checkboxes="checkboxes = $event"
167-
@update:records="getList"
167+
@update:records="getListInner"
168168
:sort="sort"
169169
:pageSize="pageSize"
170170
:totalRows="totalRows"
@@ -209,10 +209,9 @@ import ResourceListTable from '@/components/ResourceListTable.vue';
209209
import { useCoreStore } from '@/stores/core';
210210
import { useFiltersStore } from '@/stores/filters';
211211
import { callAdminForthApi, currentQuery, getIcon, setQuery } from '@/utils';
212-
import { computed, onMounted, onUnmounted, ref, watch, nextTick, type Ref } from 'vue';
212+
import { computed, onMounted, onUnmounted, ref, watch, type Ref } from 'vue';
213213
import { useRoute } from 'vue-router';
214-
import { showErrorTost } from '@/composables/useFrontendApi'
215-
import { getCustomComponent, initThreeDotsDropdown } from '@/utils';
214+
import { getCustomComponent, initThreeDotsDropdown, getList, startBulkAction } from '@/utils';
216215
import ThreeDotsMenu from '@/components/ThreeDotsMenu.vue';
217216
import { Tooltip } from '@/afcl'
218217
import type { AdminForthComponentDeclarationFull } from '@/types/Common';
@@ -228,7 +227,7 @@ import Filters from '@/components/Filters.vue';
228227
import { useAdminforth } from '@/adminforth';
229228
230229
const filtersShow = ref(false);
231-
const { confirm, alert, list } = useAdminforth();
230+
const { list } = useAdminforth();
232231
const coreStore = useCoreStore();
233232
const filtersStore = useFiltersStore();
234233
@@ -257,45 +256,6 @@ const listBufferSize = computed(() => coreStore.resource?.options?.listBufferSiz
257256
258257
const isPageLoaded = ref(false);
259258
260-
async function getList() {
261-
rows.value = null;
262-
if (!isPageLoaded.value) {
263-
return;
264-
}
265-
const data = await callAdminForthApi({
266-
path: '/get_resource_data',
267-
method: 'POST',
268-
body: {
269-
source: 'list',
270-
resourceId: route.params.resourceId,
271-
limit: pageSize.value,
272-
offset: ((page.value || 1) - 1) * pageSize.value,
273-
filters: filtersStore.filters,
274-
sort: sort.value,
275-
}
276-
});
277-
if (data.error) {
278-
showErrorTost(data.error);
279-
rows.value = [];
280-
totalRows.value = 0;
281-
return {error: data.error};
282-
}
283-
rows.value = data.data?.map((row: any) => {
284-
if (coreStore.resource?.columns?.find(c => c.primaryKey)?.foreignResource) {
285-
row._primaryKeyValue = row[coreStore.resource.columns.find(c => c.primaryKey)!.name].pk;
286-
} else if (coreStore.resource) {
287-
row._primaryKeyValue = row[coreStore.resource.columns.find(c => c.primaryKey)!.name];
288-
}
289-
return row;
290-
});
291-
totalRows.value = data.total;
292-
293-
// if checkboxes have items which are not in current data, remove them
294-
checkboxes.value = checkboxes.value.filter(pk => rows.value!.some(r => r._primaryKeyValue === pk));
295-
await nextTick();
296-
return {}
297-
}
298-
299259
function clearCheckboxes() {
300260
checkboxes.value = [];
301261
}
@@ -351,48 +311,21 @@ async function refreshExistingList(pk?: any) {
351311
return {}
352312
}
353313
314+
async function startBulkActionInner(actionId: string) {
315+
await startBulkAction(actionId, coreStore.resource!, checkboxes, bulkActionLoadingStates, getListInner);
316+
}
354317
355-
async function startBulkAction(actionId: string) {
356-
const action = coreStore.resource?.options?.bulkActions?.find(a => a.id === actionId);
357-
if (action?.confirm) {
358-
const confirmed = await confirm({
359-
message: action.confirm,
360-
});
361-
if (!confirmed) {
362-
return;
363-
}
364-
}
365-
bulkActionLoadingStates.value[actionId] = true;
366-
367-
const data = await callAdminForthApi({
368-
path: '/start_bulk_action',
369-
method: 'POST',
370-
body: {
371-
resourceId: route.params.resourceId,
372-
actionId: actionId,
373-
recordIds: checkboxes.value
374-
375-
}
376-
});
377-
bulkActionLoadingStates.value[actionId] = false;
378-
if (data?.ok) {
379-
checkboxes.value = [];
380-
await getList();
381-
382-
if (data.successMessage) {
383-
alert({
384-
message: data.successMessage,
385-
variant: 'success'
386-
});
387-
}
388-
389-
}
390-
if (data?.error) {
391-
showErrorTost(data.error);
318+
async function getListInner() {
319+
rows.value = null; // to show loading state
320+
const result = await getList(coreStore.resource!, isPageLoaded.value, page.value, pageSize.value, sort.value, checkboxes, filtersStore.filters);
321+
if (!result) {
322+
return { error: 'No result returned from getList' };
392323
}
324+
rows.value = result.rows;
325+
totalRows.value = result.totalRows ?? 0;
326+
return { error: result.error };
393327
}
394328
395-
396329
class SortQuerySerializer {
397330
static serialize(sort: {field: string, direction: 'asc' | 'desc'}[]) {
398331
return sort.map(s => `${s.field}__${s.direction}`).join(',');
@@ -471,12 +404,11 @@ async function init() {
471404
472405
watch([page, sort, () => filtersStore.filters], async () => {
473406
// console.log('🔄️ page/sort/filter change fired, page:', page.value);
474-
await getList();
407+
await getListInner();
475408
}, { deep: true });
476409
477410
list.refresh = async () => {
478-
const result = await getList();
479-
411+
const result = await getListInner();
480412
if (!result) {
481413
return {};
482414
}

0 commit comments

Comments
 (0)