adminforth 2.4.0-next.124 → 2.4.0-next.125

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.
@@ -1,6 +1,5 @@
1
- import type { FilterParams, FrontendAPIInterface } from "./types/FrontendAPI";
2
- import type { FrontendAPIInterface, ConfirmParams, AlertParams, } from '@/types/FrontendAPI';
3
- import type { AdminForthFilterOperators, AdminForthResourceColumn } from '@/types/Common';
1
+ import type { FilterParams, FrontendAPIInterface, ConfirmParams, AlertParams, } from '@/types/FrontendAPI';
2
+ import type { AdminForthFilterOperators, AdminForthResourceColumnCommon } from '@/types/Common';
4
3
  import { useToastStore } from '@/stores/toast';
5
4
  import { useModalStore } from '@/stores/modal';
6
5
  import { useCoreStore } from '@/stores/core';
@@ -85,7 +84,7 @@ class FrontendAPI implements FrontendAPIInterface {
85
84
  }
86
85
  }
87
86
 
88
- confirm(params: ConfirmParams): Promise<void> {
87
+ confirm(params: ConfirmParams): Promise<boolean> {
89
88
  return new Promise((resolve, reject) => {
90
89
  this.modalStore.setModalContent({
91
90
  content: params.message,
@@ -112,7 +111,7 @@ class FrontendAPI implements FrontendAPIInterface {
112
111
  throw new Error(`Cannot use ${this.setListFilter.name} filter on a list page`)
113
112
  } else {
114
113
  console.log(this.coreStore.resourceColumnsWithFilters,'core store')
115
- const filterField = this.coreStore.resourceColumnsWithFilters.find((col: AdminForthResourceColumn) => col.name === filter.field)
114
+ const filterField = this.coreStore.resourceColumnsWithFilters.find((col: AdminForthResourceColumnCommon) => col.name === filter.field)
116
115
  if(!filterField){
117
116
  throw new Error(`Field ${filter.field} is not available for filtering`)
118
117
  }
@@ -123,7 +122,7 @@ class FrontendAPI implements FrontendAPIInterface {
123
122
 
124
123
  setListFilter(filter: FilterParams): void {
125
124
  if(this.listFilterValidation(filter)){
126
- if(this.filtersStore.filters.some((f) => {return f.field === filter.field && f.operator === filter.operator})){
125
+ if(this.filtersStore.filters.some((f: any) => {return f.field === filter.field && f.operator === filter.operator})){
127
126
  throw new Error(`Filter ${filter.field} with operator ${filter.operator} already exists`)
128
127
  } else {
129
128
  this.filtersStore.setFilter(filter)
@@ -60,7 +60,7 @@ const optionsBase = {
60
60
  tooltip: {
61
61
  shared: true,
62
62
  intersect: false,
63
- formatter: function (value) {
63
+ formatter: function (value: any) {
64
64
  return value
65
65
  },
66
66
  },
@@ -71,7 +71,7 @@ const optionsBase = {
71
71
  fontFamily: "Inter, sans-serif",
72
72
  cssClass: 'text-xs font-normal fill-gray-500 dark:fill-gray-400'
73
73
  },
74
- formatter: function (value) {
74
+ formatter: function (value: any) {
75
75
  return value
76
76
  }
77
77
  },
@@ -6,7 +6,7 @@
6
6
  type="checkbox"
7
7
  :checked="props.modelValue"
8
8
  :disabled="props.disabled"
9
- @change="$emit('update:modelValue', $event.target.checked)"
9
+ @change="$emit('update:modelValue', ($event.target as HTMLInputElement).checked)"
10
10
  class="peer appearance-none min-w-4 min-h-4 bg-lightCheckboxBgUnchecked border border-lightCheckboxBorderColor rounded-sm checked:bg-lightCheckboxBgChecked
11
11
  focus:ring-lightFocusRing dark:focus:ring-darkFocusRing dark:focus:ring-darkFocusRing
12
12
  focus:ring-2 dark:bg-darkCheckboxBgUnchecked dark:border-darkCheckboxBorderColor dark:checked:bg-darkCheckboxBgChecked cursor-pointer"
@@ -3,7 +3,7 @@
3
3
  <form class="flex items-center justify-center w-full"
4
4
  @dragover.prevent="dragging = true"
5
5
  @dragleave.prevent="dragging = false"
6
- @drop.prevent="dragging = false; doEmit($event.dataTransfer.files)"
6
+ @drop.prevent="dragging = false; doEmit(($event.dataTransfer as DataTransfer).files)"
7
7
  >
8
8
  <label :id="id" class="flex flex-col items-center justify-center w-full border-2 border-dashed rounded-lg cursor-pointer
9
9
  hover:bg-lightDropzoneBackgroundHover hover:border-lightDropzoneBorderHover dark:hover:border-darkDropzoneBorderHover dark:hover:bg-darkDropzoneBackgroundHover"
@@ -42,7 +42,7 @@
42
42
  </div>
43
43
  <input :id="id" type="file" class="hidden"
44
44
  :accept="props.extensions.join(', ')"
45
- @change="doEmit($event.target.files)"
45
+ @change="$event.target && doEmit(($event.target as HTMLInputElement).files!)"
46
46
  :multiple="props.multiple || false"
47
47
  />
48
48
  </label>
@@ -12,7 +12,7 @@
12
12
  ref="input"
13
13
  v-bind="$attrs"
14
14
  :type="type"
15
- @input="$emit('update:modelValue', type === 'number' ? Number($event.target?.value) : $event.target?.value)"
15
+ @input="$emit('update:modelValue', type === 'number' ? Number(($event.target as HTMLInputElement)?.value) : ($event.target as HTMLInputElement)?.value)"
16
16
  :value="modelValue"
17
17
  aria-describedby="helper-text-explanation"
18
18
  class="afcl-input inline-flex bg-lightInputBackground border border-lightInputBorder text-lightInputText text-sm rounded-0 focus:ring-lightPrimary focus:border-lightPrimary dark:focus:ring-darkPrimary dark:focus:border-darkPrimary
@@ -18,7 +18,7 @@
18
18
  <script setup lang="ts">
19
19
 
20
20
  const props = defineProps<{
21
- disabled: boolean,
21
+ disabled?: boolean,
22
22
  to: string,
23
23
  }>();
24
24
 
@@ -63,8 +63,8 @@ const optionsBase = {
63
63
  show: false,
64
64
  fontFamily: "Inter, sans-serif",
65
65
  label: "",
66
- formatter: function (w) {
67
- const sum = w.globals.seriesTotals.reduce((a, b) => {
66
+ formatter: function (w: any) {
67
+ const sum = w.globals.seriesTotals.reduce((a: any, b: any) => {
68
68
  return a + b
69
69
  }, 0)
70
70
  return sum
@@ -74,7 +74,7 @@ const optionsBase = {
74
74
  show: true,
75
75
  fontFamily: "Inter, sans-serif",
76
76
  offsetY: -20,
77
- formatter: function (value) {
77
+ formatter: function (value: any) {
78
78
  return value + "k"
79
79
  },
80
80
  },
@@ -100,14 +100,14 @@ const optionsBase = {
100
100
  },
101
101
  yaxis: {
102
102
  labels: {
103
- formatter: function (value) {
103
+ formatter: function (value: any) {
104
104
  return value;
105
105
  },
106
106
  },
107
107
  },
108
108
  xaxis: {
109
109
  labels: {
110
- formatter: function (value) {
110
+ formatter: function (value: any) {
111
111
  return value;
112
112
  },
113
113
  },
@@ -52,7 +52,7 @@
52
52
  <label v-if="!$slots.item" :for="item.value">{{ item.label }}</label>
53
53
  </div>
54
54
  <div v-if="!filteredItems.length" class="px-4 py-2 cursor-pointer text-lightDropdownOptionsText dark:text-darkDropdownOptionsText">
55
- {{ options.length ? $t('No results found') : $t('No items here') }}
55
+ {{ options?.length ? $t('No results found') : $t('No items here') }}
56
56
  </div>
57
57
 
58
58
  <div v-if="$slots['extra-item']" class="px-4 py-2 dark:text-gray-400">
@@ -76,7 +76,7 @@
76
76
  <label v-if="!$slots.item" :for="item.value">{{ item.label }}</label>
77
77
  </div>
78
78
  <div v-if="!filteredItems.length" class="px-4 py-2 cursor-pointer text-lightDropdownOptionsText dark:text-darkDropdownOptionsText">
79
- {{ options.length ? $t('No results found') : $t('No items here') }}
79
+ {{ options?.length ? $t('No results found') : $t('No items here') }}
80
80
  </div>
81
81
  <div v-if="$slots['extra-item']" class="px-4 py-2 dark:text-darkDropdownOptionsText">
82
82
  <slot name="extra-item"></slot>
@@ -114,14 +114,15 @@
114
114
  </template>
115
115
 
116
116
  <script setup lang="ts">
117
- import { ref, computed, onMounted, onUnmounted, watch, nextTick, type Ref } from 'vue';
117
+ import { ref, computed, onMounted, onUnmounted, watch, nextTick,type PropType, type Ref } from 'vue';
118
118
  import { IconCaretDownSolid } from '@iconify-prerendered/vue-flowbite';
119
119
  import { useElementSize } from '@vueuse/core'
120
120
 
121
121
  const props = defineProps({
122
122
  options: Array,
123
123
  modelValue: {
124
- default: undefined,
124
+ type: Array as PropType<(string | number)[]>,
125
+ default: () => [],
125
126
  },
126
127
  multiple: {
127
128
  type: Boolean,
@@ -178,14 +179,14 @@ function inputInput() {
178
179
  function updateFromProps() {
179
180
  if (props.modelValue !== undefined) {
180
181
  if (!props.multiple) {
181
- const el = props.options.find(item => item.value === props.modelValue);
182
+ const el = props.options?.find((item: any) => item.value === props.modelValue);
182
183
  if (el) {
183
184
  selectedItems.value = [el];
184
185
  } else {
185
186
  selectedItems.value = [];
186
187
  }
187
188
  } else {
188
- selectedItems.value = props.options.filter(item => props.modelValue.includes(item.value));
189
+ selectedItems.value = props.options?.filter((item: any) => props.modelValue?.includes(item.value)) || [];
189
190
  }
190
191
  }
191
192
  }
@@ -268,7 +269,7 @@ onMounted(() => {
268
269
  }
269
270
  });
270
271
 
271
- const filteredItems = computed(() => {
272
+ const filteredItems: Ref<any[]> = computed(() => {
272
273
 
273
274
  if (props.searchDisabled) {
274
275
  return props.options || [];
@@ -295,7 +296,7 @@ const removeClickListener = () => {
295
296
  document.removeEventListener('click', handleClickOutside);
296
297
  };
297
298
 
298
- const toogleItem = (item) => {
299
+ const toogleItem = (item: any) => {
299
300
  if (selectedItems.value.includes(item)) {
300
301
  selectedItems.value = selectedItems.value.filter(i => i.value !== item.value);
301
302
  } else {
@@ -5,7 +5,7 @@
5
5
  value="" class="sr-only peer"
6
6
  :disabled="props.disabled"
7
7
  :checked="props.modelValue"
8
- @change="$emit('update:modelValue', $event.target.checked)"
8
+ @change="$emit('update:modelValue', ($event.target as HTMLInputElement).checked)"
9
9
  >
10
10
  <div class="afcl-toggle border border-lightToggleBorderUnactive relative min-w-11 min-h-6 bg-lightToggleBgUnactive peer-focus:outline-none peer-focus:ring-4
11
11
  peer-focus:ring-lightToggleRing dark:peer-focus:ring-darkToggleRing rounded-full peer dark:bg-darkToggleBgUnactive
@@ -47,8 +47,8 @@
47
47
  </div>
48
48
  <span
49
49
  class="bg-red-100 text-red-800 text-xs font-medium me-1 px-1 py-0.5 rounded dark:bg-gray-700 dark:text-red-400 border border-red-400"
50
- v-if="sort.findIndex((s) => s.field === c.name) !== -1 && sort?.length > 1">
51
- {{ sort.findIndex((s) => s.field === c.name) + 1 }}
50
+ v-if="sort.findIndex((s: any) => s.field === c.name) !== -1 && sort?.length > 1">
51
+ {{ sort.findIndex((s: any) => s.field === c.name) + 1 }}
52
52
  </span>
53
53
 
54
54
  </div>
@@ -64,7 +64,7 @@
64
64
  <!-- table header end -->
65
65
  <SkeleteLoader
66
66
  v-if="!rows"
67
- :columns="resource?.columns.filter(c => c.showIn.list).length + 2"
67
+ :columns="resource?.columns.filter((c: AdminForthResourceColumnInputCommon) => c.showIn?.list).length + 2"
68
68
  :rows="rowHeights.length || 3"
69
69
  :row-heights="rowHeights"
70
70
  :column-widths="columnWidths"
@@ -93,8 +93,8 @@
93
93
  <td class="w-4 p-4 cursor-default" @click="(e)=>e.stopPropagation()">
94
94
  <Checkbox
95
95
  :model-value="checkboxesInternal.includes(row._primaryKeyValue)"
96
- @change="(e)=>{addToCheckedValues(row._primaryKeyValue)}"
97
- @click="(e)=>e.stopPropagation()"
96
+ @change="(e: any)=>{addToCheckedValues(row._primaryKeyValue)}"
97
+ @click="(e: any)=>e.stopPropagation()"
98
98
  >
99
99
  <span class="sr-only">{{ $t('checkbox') }}</span>
100
100
  </Checkbox>
@@ -103,8 +103,8 @@
103
103
  <td v-for="c in columnsListed" class="px-2 md:px-3 lg:px-6 py-4">
104
104
  <!-- if c.name in listComponentsPerColumn, render it. If not, render ValueRenderer -->
105
105
  <component
106
- :is="c?.components?.list ? getCustomComponent(c.components.list) : ValueRenderer"
107
- :meta="c?.components?.list?.meta"
106
+ :is="c?.components?.list ? getCustomComponent(typeof c.components.list === 'string' ? { file: c.components.list } : c.components.list) : ValueRenderer"
107
+ :meta="typeof c?.components?.list === 'object' ? c.components.list.meta : undefined"
108
108
  :column="c"
109
109
  :record="row"
110
110
  :adminUser="coreStore.adminUser"
@@ -115,7 +115,7 @@
115
115
  <div class="flex text-lightPrimary dark:text-darkPrimary items-center">
116
116
  <Tooltip>
117
117
  <RouterLink
118
- v-if="resource.options?.allowedActions.show"
118
+ v-if="resource.options?.allowedActions?.show"
119
119
  :to="{
120
120
  name: 'resource-show',
121
121
  params: {
@@ -135,7 +135,7 @@
135
135
 
136
136
  <Tooltip>
137
137
  <RouterLink
138
- v-if="resource.options?.allowedActions.edit"
138
+ v-if="resource.options?.allowedActions?.edit"
139
139
  :to="{
140
140
  name: 'resource-edit',
141
141
  params: {
@@ -153,7 +153,7 @@
153
153
 
154
154
  <Tooltip>
155
155
  <button
156
- v-if="resource.options?.allowedActions.delete"
156
+ v-if="resource.options?.allowedActions?.delete"
157
157
  @click="deleteRecord(row)"
158
158
  >
159
159
  <IconTrashBinSolid class="af-delete-icon w-5 h-5 me-2"/>
@@ -308,7 +308,7 @@ import {
308
308
  } from '@iconify-prerendered/vue-flowbite';
309
309
  import router from '@/router';
310
310
  import { Tooltip } from '@/afcl';
311
- import type { AdminForthResourceCommon } from '@/types/Common';
311
+ import type { AdminForthResourceCommon, AdminForthResourceColumnInputCommon, AdminForthResourceColumnCommon } from '@/types/Common';
312
312
  import adminforth from '@/adminforth';
313
313
  import Checkbox from '@/afcl/Checkbox.vue';
314
314
 
@@ -339,7 +339,7 @@ const emits = defineEmits([
339
339
  const checkboxesInternal: Ref<any[]> = ref([]);
340
340
  const pageInput = ref('1');
341
341
  const page = ref(1);
342
- const sort = ref([]);
342
+ const sort: Ref<Array<{field: string, direction: string}>> = ref([]);
343
343
 
344
344
 
345
345
  const from = computed(() => ((page.value || 1) - 1) * props.pageSize + 1);
@@ -348,11 +348,11 @@ const to = computed(() => Math.min((page.value || 1) * props.pageSize, props.tot
348
348
  watch(() => page.value, (newPage) => {
349
349
  emits('update:page', newPage);
350
350
  });
351
- async function onPageKeydown(event) {
351
+ async function onPageKeydown(event: any) {
352
352
  // page input should accept only numbers, arrow keys and backspace
353
353
  if (['Enter', 'Space'].includes(event.code) ||
354
354
  (!['Backspace', 'ArrowRight', 'ArrowLeft'].includes(event.code)
355
- && isNaN(String.fromCharCode(event.keyCode)))) {
355
+ && isNaN(Number(String.fromCharCode(event.keyCode || 0))))) {
356
356
  event.preventDefault();
357
357
  if (event.code === 'Enter') {
358
358
  validatePageInput();
@@ -373,7 +373,7 @@ watch(() => props.checkboxes, (newCheckboxes) => {
373
373
  checkboxesInternal.value = newCheckboxes;
374
374
  });
375
375
 
376
- watch(() => props.sort, (newSort) => {
376
+ watch(() => props.sort, (newSort: any) => {
377
377
  sort.value = newSort;
378
378
  });
379
379
 
@@ -384,17 +384,17 @@ watch(() => props.page, (newPage) => {
384
384
  page.value = newPage;
385
385
  });
386
386
 
387
- const rowRefs = useTemplateRef('rowRefs');
388
- const headerRefs = useTemplateRef('headerRefs');
389
- const rowHeights = ref([]);
390
- const columnWidths = ref([]);
387
+ const rowRefs = useTemplateRef<HTMLElement[]>('rowRefs');
388
+ const headerRefs = useTemplateRef<HTMLElement[]>('headerRefs');
389
+ const rowHeights = ref<number[]>([]);
390
+ const columnWidths = ref<number[]>([]);
391
391
  watch(() => props.rows, (newRows) => {
392
392
  // rows are set to null when new records are loading
393
- rowHeights.value = newRows || !rowRefs.value ? [] : rowRefs.value.map((el) => el.offsetHeight);
394
- columnWidths.value = newRows || !headerRefs.value ? [] : [48, ...headerRefs.value.map((el) => el.offsetWidth)];
393
+ rowHeights.value = newRows || !rowRefs.value ? [] : rowRefs.value.map((el: HTMLElement) => el.offsetHeight);
394
+ columnWidths.value = newRows || !headerRefs.value ? [] : [48, ...headerRefs.value.map((el: HTMLElement) => el.offsetWidth)];
395
395
  });
396
396
 
397
- function addToCheckedValues(id) {
397
+ function addToCheckedValues(id: string) {
398
398
  if (checkboxesInternal.value.includes(id)) {
399
399
  checkboxesInternal.value = checkboxesInternal.value.filter((item) => item !== id);
400
400
  } else {
@@ -403,17 +403,17 @@ function addToCheckedValues(id) {
403
403
  checkboxesInternal.value = [ ...checkboxesInternal.value ]
404
404
  }
405
405
 
406
- const columnsListed = computed(() => props.resource?.columns?.filter(c => c.showIn.list));
406
+ const columnsListed = computed(() => props.resource?.columns?.filter((c: AdminForthResourceColumnCommon) => c.showIn?.list));
407
407
 
408
- async function selectAll(value) {
408
+ async function selectAll() {
409
409
  if (!allFromThisPageChecked.value) {
410
- props.rows.forEach((r) => {
410
+ props.rows?.forEach((r) => {
411
411
  if (!checkboxesInternal.value.includes(r._primaryKeyValue)) {
412
412
  checkboxesInternal.value.push(r._primaryKeyValue)
413
413
  }
414
414
  });
415
415
  } else {
416
- props.rows.forEach((r) => {
416
+ props.rows?.forEach((r) => {
417
417
  checkboxesInternal.value = checkboxesInternal.value.filter((item) => item !== r._primaryKeyValue);
418
418
  });
419
419
  }
@@ -426,15 +426,15 @@ const allFromThisPageChecked = computed(() => {
426
426
  if (!props.rows || !props.rows.length) return false;
427
427
  return props.rows.every((r) => checkboxesInternal.value.includes(r._primaryKeyValue));
428
428
  });
429
- const ascArr = computed(() => sort.value.filter((s) => s.direction === 'asc').map((s) => s.field));
430
- const descArr = computed(() => sort.value.filter((s) => s.direction === 'desc').map((s) => s.field));
429
+ const ascArr = computed(() => sort.value.filter((s:any) => s.direction === 'asc').map((s: any) => s.field));
430
+ const descArr = computed(() => sort.value.filter((s: any) => s.direction === 'desc').map((s: any) => s.field));
431
431
 
432
432
 
433
- function onSortButtonClick(event, field) {
433
+ function onSortButtonClick(event: any, field: string) {
434
434
  // if ctrl key is pressed, add to sort otherwise sort by this field
435
435
  // in any case if field is already in sort, toggle direction
436
436
 
437
- const sortIndex = sort.value.findIndex((s) => s.field === field);
437
+ const sortIndex = sort.value.findIndex((s: any) => s.field === field);
438
438
  if (sortIndex === -1) {
439
439
  // field is not in sort, add it
440
440
  if (event.ctrlKey) {
@@ -445,9 +445,9 @@ function onSortButtonClick(event, field) {
445
445
  } else {
446
446
  const sortField = sort.value[sortIndex];
447
447
  if (sortField.direction === 'asc') {
448
- sort.value = sort.value.map((s) => s.field === field ? {field, direction: 'desc'} : s);
448
+ sort.value = sort.value.map((s: any) => s.field === field ? {field, direction: 'desc'} : s);
449
449
  } else {
450
- sort.value = sort.value.filter((s) => s.field !== field);
450
+ sort.value = sort.value.filter((s: any) => s.field !== field);
451
451
  }
452
452
  }
453
453
  }
@@ -455,11 +455,11 @@ function onSortButtonClick(event, field) {
455
455
 
456
456
  const clickTarget = ref(null);
457
457
 
458
- async function onClick(e,row) {
458
+ async function onClick(e: any, row: any) {
459
459
  if(clickTarget.value === e.target) return;
460
460
  clickTarget.value = e.target;
461
461
  await new Promise((resolve) => setTimeout(resolve, 100));
462
- if (window.getSelection().toString()) return;
462
+ if (window.getSelection()?.toString()) return;
463
463
  else {
464
464
  if (row._clickUrl === null) {
465
465
  // user asked to nothing on click
@@ -474,7 +474,7 @@ async function onClick(e,row) {
474
474
  router.resolve({
475
475
  name: 'resource-show',
476
476
  params: {
477
- resourceId: props.resource.resourceId,
477
+ resourceId: props.resource?.resourceId,
478
478
  primaryKey: row._primaryKeyValue,
479
479
  },
480
480
  }).href,
@@ -492,7 +492,7 @@ async function onClick(e,row) {
492
492
  router.push({
493
493
  name: 'resource-show',
494
494
  params: {
495
- resourceId: props.resource.resourceId,
495
+ resourceId: props.resource?.resourceId,
496
496
  primaryKey: row._primaryKeyValue,
497
497
  },
498
498
  });
@@ -501,7 +501,7 @@ async function onClick(e,row) {
501
501
  }
502
502
  }
503
503
 
504
- async function deleteRecord(row) {
504
+ async function deleteRecord(row: any) {
505
505
  const data = await adminforth.confirm({
506
506
  message: t('Are you sure you want to delete this item?'),
507
507
  yes: t('Delete'),
@@ -513,7 +513,7 @@ async function deleteRecord(row) {
513
513
  path: '/delete_record',
514
514
  method: 'POST',
515
515
  body: {
516
- resourceId: props.resource.resourceId,
516
+ resourceId: props.resource?.resourceId,
517
517
  primaryKey: row._primaryKeyValue,
518
518
  }
519
519
  });
@@ -531,16 +531,16 @@ async function deleteRecord(row) {
531
531
  }
532
532
  }
533
533
 
534
- const actionLoadingStates = ref({});
534
+ const actionLoadingStates = ref<Record<string | number, boolean>>({});
535
535
 
536
- async function startCustomAction(actionId, row) {
536
+ async function startCustomAction(actionId: string, row: any) {
537
537
  actionLoadingStates.value[actionId] = true;
538
538
 
539
539
  const data = await callAdminForthApi({
540
540
  path: '/start_custom_action',
541
541
  method: 'POST',
542
542
  body: {
543
- resourceId: props.resource.resourceId,
543
+ resourceId: props.resource?.resourceId,
544
544
  actionId: actionId,
545
545
  recordId: row._primaryKeyValue
546
546
  }
@@ -578,7 +578,7 @@ async function startCustomAction(actionId, row) {
578
578
  }
579
579
  }
580
580
 
581
- function onPageInput(event) {
581
+ function onPageInput(event: any) {
582
582
  pageInput.value = event.target.innerText;
583
583
  }
584
584