adminforth 1.2.87 → 1.2.89
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/dist/modules/restApi.js +9 -0
- package/dist/spa/.vscode/extensions.json +6 -0
- package/dist/spa/index.html +4 -4
- package/dist/spa/package-lock.json +6 -421
- package/dist/spa/package.json +2 -10
- package/dist/spa/public/favicon.ico +0 -0
- package/dist/spa/spa/.eslintrc.cjs +14 -0
- package/dist/spa/spa/.vscode/extensions.json +6 -0
- package/dist/spa/spa/README.md +39 -0
- package/dist/spa/spa/env.d.ts +1 -0
- package/dist/spa/spa/index.html +23 -0
- package/dist/spa/spa/package-lock.json +4573 -0
- package/dist/spa/spa/package.json +49 -0
- package/dist/spa/spa/postcss.config.js +6 -0
- package/dist/spa/spa/public/favicon.ico +0 -0
- package/dist/spa/spa/src/App.vue +314 -0
- package/dist/spa/spa/src/assets/base.css +0 -0
- package/dist/spa/spa/src/assets/logo.svg +19 -0
- package/dist/spa/spa/src/components/AcceptModal.vue +45 -0
- package/dist/spa/spa/src/components/Breadcrumbs.vue +40 -0
- package/dist/spa/spa/src/components/BreadcrumbsWithButtons.vue +26 -0
- package/dist/spa/spa/src/components/CustomDatePicker.vue +174 -0
- package/dist/spa/spa/src/components/CustomDateRangePicker.vue +218 -0
- package/dist/spa/spa/src/components/Dropdown.vue +168 -0
- package/dist/spa/spa/src/components/Filters.vue +222 -0
- package/dist/spa/spa/src/components/HelloWorld.vue +17 -0
- package/dist/spa/spa/src/components/MenuLink.vue +24 -0
- package/dist/spa/spa/src/components/ResourceForm.vue +289 -0
- package/dist/spa/{src → spa/src}/components/ResourceListTable.vue +3 -6
- package/dist/spa/spa/src/components/SingleSkeletLoader.vue +13 -0
- package/dist/spa/{src → spa/src}/components/Toast.vue +3 -9
- package/dist/spa/spa/src/components/ValueRenderer.vue +66 -0
- package/dist/spa/spa/src/components/icons/IconCalendar.vue +5 -0
- package/dist/spa/spa/src/components/icons/IconCommunity.vue +7 -0
- package/dist/spa/spa/src/components/icons/IconDocumentation.vue +7 -0
- package/dist/spa/spa/src/components/icons/IconEcosystem.vue +7 -0
- package/dist/spa/spa/src/components/icons/IconSupport.vue +7 -0
- package/dist/spa/spa/src/components/icons/IconTime.vue +5 -0
- package/dist/spa/spa/src/components/icons/IconTooling.vue +19 -0
- package/dist/spa/spa/src/index.scss +27 -0
- package/dist/spa/spa/src/main.ts +18 -0
- package/dist/spa/spa/src/router/index.ts +63 -0
- package/dist/spa/spa/src/stores/core.ts +144 -0
- package/dist/spa/spa/src/stores/modal.ts +48 -0
- package/dist/spa/spa/src/utils.ts +103 -0
- package/dist/spa/spa/src/views/CreateView.vue +156 -0
- package/dist/spa/spa/src/views/EditView.vue +157 -0
- package/dist/spa/spa/src/views/HomeView.vue +8 -0
- package/dist/spa/spa/src/views/ListView.vue +258 -0
- package/dist/spa/spa/src/views/LoginView.vue +143 -0
- package/dist/spa/spa/src/views/ResourceParent.vue +17 -0
- package/dist/spa/spa/src/views/ShowView.vue +184 -0
- package/dist/spa/spa/tailwind.config.js +17 -0
- package/dist/spa/spa/tsconfig.app.json +14 -0
- package/dist/spa/spa/tsconfig.json +11 -0
- package/dist/spa/spa/tsconfig.node.json +19 -0
- package/dist/spa/spa/vite.config.ts +56 -0
- package/dist/spa/src/App.vue +94 -236
- package/dist/spa/src/assets/base.css +0 -2
- package/dist/spa/src/assets/logo.svg +1 -19
- package/dist/spa/src/components/AcceptModal.vue +10 -3
- package/dist/spa/src/components/Breadcrumbs.vue +2 -3
- package/dist/spa/src/components/BreadcrumbsWithButtons.vue +1 -1
- package/dist/spa/src/components/CustomDatePicker.vue +10 -25
- package/dist/spa/src/components/CustomDateRangePicker.vue +5 -14
- package/dist/spa/src/components/Dropdown.vue +5 -19
- package/dist/spa/src/components/Filters.vue +38 -103
- package/dist/spa/src/components/MenuLink.vue +3 -3
- package/dist/spa/src/components/ResourceForm.vue +116 -205
- package/dist/spa/src/components/ValueRenderer.vue +8 -30
- package/dist/spa/src/index.scss +1 -2
- package/dist/spa/src/main.ts +2 -2
- package/dist/spa/src/router/index.ts +19 -29
- package/dist/spa/src/stores/core.ts +59 -65
- package/dist/spa/src/stores/modal.ts +3 -13
- package/dist/spa/src/utils.ts +10 -69
- package/dist/spa/src/views/CreateView.vue +16 -69
- package/dist/spa/src/views/EditView.vue +14 -68
- package/dist/spa/src/views/HomeView.vue +8 -0
- package/dist/spa/src/views/ListView.vue +371 -100
- package/dist/spa/src/views/LoginView.vue +29 -67
- package/dist/spa/src/views/ResourceParent.vue +2 -1
- package/dist/spa/src/views/ShowView.vue +25 -116
- package/dist/spa/tailwind.config.js +3 -8
- package/dist/spa/vite.config.ts +0 -13
- package/dist/types.js +30 -0
- package/modules/restApi.ts +14 -1
- package/package.json +1 -1
- package/spa/src/components/MenuLink.vue +3 -0
- package/types/AdminForthConfig.ts +6 -0
- package/dist/spa/src/types/AdminForthConfig.ts +0 -1477
- package/dist/spa/src/types/FrontendAPI.ts +0 -121
- /package/dist/spa/{public → spa/public}/assets/favicon.png +0 -0
- /package/dist/spa/{src → spa/src}/components/CustomRangePicker.vue +0 -0
- /package/dist/spa/{src → spa/src}/components/SkeleteLoader.vue +0 -0
- /package/dist/spa/{src → spa/src}/composables/useFrontendApi.ts +0 -0
- /package/dist/spa/{src → spa/src}/composables/useStores.ts +0 -0
- /package/dist/spa/{src → spa/src}/spa_types/core.ts +0 -0
- /package/dist/spa/{src → spa/src}/stores/filters.ts +0 -0
- /package/dist/spa/{src → spa/src}/stores/toast.ts +0 -0
- /package/dist/spa/{src → spa/src}/stores/user.ts +0 -0
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
<div class="mx-auto grid grid-cols-2 gap-4 mb-2" :class="{hidden: !showTimeInputs}">
|
|
27
27
|
<div>
|
|
28
28
|
<div class="relative">
|
|
29
|
-
<div class="absolute inset-y-0 end-0 top-0 flex items-center pe-3.5
|
|
29
|
+
<div class="absolute inset-y-0 end-0 top-0 flex items-center pe-3.5">
|
|
30
30
|
<IconTime class="w-4 h-4 text-gray-500 dark:text-gray-400 bg-white dark:bg-gray-700"/>
|
|
31
31
|
</div>
|
|
32
32
|
|
|
@@ -101,9 +101,6 @@ const endDate = ref('');
|
|
|
101
101
|
const startTime = ref('');
|
|
102
102
|
const endTime = ref('');
|
|
103
103
|
|
|
104
|
-
const datepickerStartObject = ref('')
|
|
105
|
-
const datepickerEndObject = ref('')
|
|
106
|
-
|
|
107
104
|
const start = computed(() => {
|
|
108
105
|
if (!startDate.value) {
|
|
109
106
|
return;
|
|
@@ -135,11 +132,11 @@ const end = computed(() => {
|
|
|
135
132
|
})
|
|
136
133
|
|
|
137
134
|
function updateFromProps() {
|
|
138
|
-
if (
|
|
135
|
+
if (props.valueStart === undefined) {
|
|
139
136
|
datepickerStartEl.value.value = '';
|
|
140
137
|
startTime.value = '';
|
|
141
138
|
}
|
|
142
|
-
if (
|
|
139
|
+
if (props.valueEnd === undefined) {
|
|
143
140
|
datepickerEndEl.value.value = '';
|
|
144
141
|
endTime.value = '';
|
|
145
142
|
}
|
|
@@ -165,9 +162,9 @@ watch(end, () => {
|
|
|
165
162
|
|
|
166
163
|
function initDatepickers() {
|
|
167
164
|
|
|
168
|
-
|
|
165
|
+
new Datepicker(datepickerStartEl.value, {format: 'dd M yyyy'});
|
|
169
166
|
|
|
170
|
-
|
|
167
|
+
new Datepicker(datepickerEndEl.value, {format: 'dd M yyyy'});
|
|
171
168
|
addChangeDateListener();
|
|
172
169
|
}
|
|
173
170
|
|
|
@@ -181,11 +178,6 @@ function removeChangeDateListener() {
|
|
|
181
178
|
datepickerEndEl.value.removeEventListener('changeDate', setEndDate);
|
|
182
179
|
}
|
|
183
180
|
|
|
184
|
-
function destroyDatepickerElement() {
|
|
185
|
-
datepickerStartObject.value.destroy();
|
|
186
|
-
datepickerEndObject.value.destroy();
|
|
187
|
-
}
|
|
188
|
-
|
|
189
181
|
function setStartDate(event) {
|
|
190
182
|
startDate.value = event.detail.date
|
|
191
183
|
}
|
|
@@ -213,6 +205,5 @@ onMounted(() => {
|
|
|
213
205
|
|
|
214
206
|
onBeforeUnmount(() => {
|
|
215
207
|
removeChangeDateListener();
|
|
216
|
-
destroyDatepickerElement();
|
|
217
208
|
})
|
|
218
209
|
</script>
|
|
@@ -6,11 +6,10 @@
|
|
|
6
6
|
v-model="search"
|
|
7
7
|
@focus="showDropdown = true"
|
|
8
8
|
class="block w-full pl-3 pr-10 py-2 border border-gray-300 rounded-md leading-5 bg-white placeholder-gray-500 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 sm:text-sm transition duration-150 ease-in-out dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
|
9
|
-
:placeholder="selectedItems.length ? '' :
|
|
9
|
+
:placeholder="selectedItems.length ? '' : 'Select...'"
|
|
10
10
|
/>
|
|
11
11
|
<div class="absolute inset-y-0 left-2 flex items-center pr-2 flex-wrap">
|
|
12
|
-
|
|
13
|
-
<div v-for="item in selectedItems" :key="item?.name" class="bg-blue-100 text-blue-800 text-xs font-medium me-2 px-2.5 py-0.5 rounded dark:bg-blue-900 dark:text-blue-300">
|
|
12
|
+
<div v-for="item in selectedItems" :key="item.name" class="bg-blue-100 text-blue-800 text-xs font-medium me-2 px-2.5 py-0.5 rounded dark:bg-blue-900 dark:text-blue-300">
|
|
14
13
|
<span>{{ item.label }}</span>
|
|
15
14
|
<button
|
|
16
15
|
type="button"
|
|
@@ -35,7 +34,7 @@
|
|
|
35
34
|
<IconCaretUpSolid v-else class="h-5 w-5 text-gray-400" />
|
|
36
35
|
</div>
|
|
37
36
|
</div>
|
|
38
|
-
<div v-if="showDropdown" class="absolute z-10 mt-1 w-full bg-white shadow-lg
|
|
37
|
+
<div v-if="showDropdown" class="absolute z-10 mt-1 w-full bg-white shadow-lg rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm">
|
|
39
38
|
<div
|
|
40
39
|
v-for="item in filteredItems"
|
|
41
40
|
:key="item.value"
|
|
@@ -67,11 +66,6 @@ const props = defineProps({
|
|
|
67
66
|
type: Boolean,
|
|
68
67
|
default: false,
|
|
69
68
|
},
|
|
70
|
-
placeholder: {
|
|
71
|
-
type: String,
|
|
72
|
-
default: '',
|
|
73
|
-
|
|
74
|
-
},
|
|
75
69
|
});
|
|
76
70
|
|
|
77
71
|
const emit = defineEmits(['update:modelValue']);
|
|
@@ -82,14 +76,10 @@ const showDropdown = ref(false);
|
|
|
82
76
|
const selectedItems = ref([]);
|
|
83
77
|
|
|
84
78
|
function updateFromProps() {
|
|
79
|
+
console.log('⚡ updateFromProps', props.modelValue)
|
|
85
80
|
if (props.modelValue !== undefined) {
|
|
86
81
|
if (props.single) {
|
|
87
|
-
|
|
88
|
-
if (el) {
|
|
89
|
-
selectedItems.value = [el];
|
|
90
|
-
} else {
|
|
91
|
-
selectedItems.value = [];
|
|
92
|
-
}
|
|
82
|
+
selectedItems.value = [props.options.find(item => item.value === props.modelValue)];
|
|
93
83
|
} else {
|
|
94
84
|
selectedItems.value = props.options.filter(item => props.modelValue.includes(item.value));
|
|
95
85
|
}
|
|
@@ -103,10 +93,6 @@ onMounted(() => {
|
|
|
103
93
|
updateFromProps();
|
|
104
94
|
});
|
|
105
95
|
|
|
106
|
-
watch(() => props.options, () => {
|
|
107
|
-
updateFromProps();
|
|
108
|
-
});
|
|
109
|
-
|
|
110
96
|
addClickListener();
|
|
111
97
|
|
|
112
98
|
});
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
<!-- drawer component -->
|
|
3
3
|
<div id="drawer-navigation"
|
|
4
4
|
|
|
5
|
-
class="fixed
|
|
5
|
+
class="fixed top-14 right-0 z-40 p-4 overflow-y-auto transition-transform translate-x-full bg-white w-80 dark:bg-gray-800 shadow-xl"
|
|
6
6
|
|
|
7
7
|
:class="show ? 'top-0 transform-none' : ''"
|
|
8
8
|
tabindex="-1" aria-labelledby="drawer-navigation-label"
|
|
9
|
-
:style="{ height: `calc(100vh ` }"
|
|
9
|
+
:style="{ height: `calc(100vh - 3.5rem)` }"
|
|
10
10
|
>
|
|
11
11
|
<h5 id="drawer-navigation-label" class="text-base font-semibold text-gray-500 uppercase dark:text-gray-400">
|
|
12
12
|
Filters
|
|
@@ -22,17 +22,11 @@
|
|
|
22
22
|
<li v-for="c in columnsWithFilter" :key="c">
|
|
23
23
|
<p class="dark:text-gray-400">{{ c.label }}</p>
|
|
24
24
|
|
|
25
|
-
<Dropdown
|
|
26
|
-
v-if="c.
|
|
27
|
-
:options="columnOptions[c.name] || []"
|
|
28
|
-
@update:modelValue="setFilterItem({ column: c, operator: 'in', value: $event })"
|
|
29
|
-
:modelValue="filtersStore.filters.find(f => f.field === c.name && f.operator === 'in')?.value || []"
|
|
30
|
-
/>
|
|
31
|
-
<Dropdown
|
|
32
|
-
v-else-if="c.type === 'boolean'"
|
|
25
|
+
<Dropdown
|
|
26
|
+
v-if="c.type === 'boolean'"
|
|
33
27
|
:options="[{ label: 'Yes', value: true }, { label: 'No', value: false }, { label: 'Unset', value: null }]"
|
|
34
28
|
@update:modelValue="setFilterItem({ column: c, operator: 'in', value: $event })"
|
|
35
|
-
:modelValue="
|
|
29
|
+
:modelValue="filters.find(f => f.field === c.name && f.operator === 'in')?.value || []"
|
|
36
30
|
/>
|
|
37
31
|
|
|
38
32
|
<Dropdown
|
|
@@ -40,7 +34,7 @@
|
|
|
40
34
|
:options="c.enum"
|
|
41
35
|
:allowCustom="c.allowCustom"
|
|
42
36
|
@update:modelValue="setFilterItem({ column: c, operator: 'in', value: $event })"
|
|
43
|
-
:modelValue="
|
|
37
|
+
:modelValue="filters.find(f => f.field === c.name && f.operator === 'in')?.value || []"
|
|
44
38
|
/>
|
|
45
39
|
|
|
46
40
|
<input
|
|
@@ -54,9 +48,9 @@
|
|
|
54
48
|
<CustomDateRangePicker
|
|
55
49
|
v-else-if="['datetime'].includes(c.type)"
|
|
56
50
|
:column="c"
|
|
57
|
-
:valueStart="
|
|
51
|
+
:valueStart="filters.find(f => f.field === c.name && f.operator === 'gte')?.value || undefined"
|
|
58
52
|
@update:valueStart="setFilterItem({ column: c, operator: 'gte', value: $event || undefined })"
|
|
59
|
-
:valueEnd="
|
|
53
|
+
:valueEnd="filters.find(f => f.field === c.name && f.operator === 'lte')?.value || undefined"
|
|
60
54
|
@update:valueEnd="setFilterItem({ column: c, operator: 'lte', value: $event || undefined })"
|
|
61
55
|
/>
|
|
62
56
|
|
|
@@ -68,32 +62,22 @@
|
|
|
68
62
|
:value="getFilterItem({ column: c, operator: 'ilike' })"
|
|
69
63
|
>
|
|
70
64
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
:value="getFilterItem({ column: c, operator: 'gte' })"
|
|
88
|
-
>
|
|
89
|
-
<input
|
|
90
|
-
type="number" aria-describedby="helper-text-explanation"
|
|
91
|
-
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-20 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
|
92
|
-
placeholder="To"
|
|
93
|
-
@input="setFilterItem({ column: c, operator: 'lte', value: $event.target.value || undefined})"
|
|
94
|
-
:value="getFilterItem({ column: c, operator: 'lte' })"
|
|
95
|
-
>
|
|
96
|
-
</div>
|
|
65
|
+
<div v-else-if="['integer', 'decimal', 'float'].includes(c.type)" class="flex gap-2">
|
|
66
|
+
<input
|
|
67
|
+
type="number" aria-describedby="helper-text-explanation"
|
|
68
|
+
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-20 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
|
69
|
+
placeholder="From"
|
|
70
|
+
@input="setFilterItem({ column: c, operator: 'gte', value: $event.target.value || undefined })"
|
|
71
|
+
:value="getFilterItem({ column: c, operator: 'gte' })"
|
|
72
|
+
>
|
|
73
|
+
<input
|
|
74
|
+
type="number" aria-describedby="helper-text-explanation"
|
|
75
|
+
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-20 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
|
76
|
+
placeholder="To"
|
|
77
|
+
@input="setFilterItem({ column: c, operator: 'lte', value: $event.target.value || undefined})"
|
|
78
|
+
:value="getFilterItem({ column: c, operator: 'lte' })"
|
|
79
|
+
>
|
|
80
|
+
</div>
|
|
97
81
|
|
|
98
82
|
</li>
|
|
99
83
|
</ul>
|
|
@@ -101,71 +85,33 @@
|
|
|
101
85
|
|
|
102
86
|
<div class="flex justify-end gap-2">
|
|
103
87
|
<button
|
|
104
|
-
:disabled="!
|
|
88
|
+
:disabled="!filters.length"
|
|
105
89
|
type="button"
|
|
106
|
-
class="flex items-center py-1 px-3 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded border border-gray-300 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700 disabled:opacity-50 disabled:cursor-not-allowed"
|
|
90
|
+
class="flex items-center py-1 px-3 mb-2 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded border border-gray-300 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700 disabled:opacity-50 disabled:cursor-not-allowed"
|
|
107
91
|
@click="clear">Clear all</button>
|
|
108
92
|
|
|
109
93
|
</div>
|
|
110
94
|
</div>
|
|
111
95
|
|
|
112
|
-
<div v-if="show"
|
|
96
|
+
<div v-if="show" drawer-backdrop="" class="bg-gray-900/50 dark:bg-gray-900/80 fixed inset-0 z-30"
|
|
113
97
|
@click="$emit('hide')">
|
|
114
98
|
</div>
|
|
115
99
|
</template>
|
|
116
100
|
|
|
117
101
|
<script setup>
|
|
118
|
-
import { watch, computed
|
|
102
|
+
import { watch, computed } from 'vue'
|
|
119
103
|
import Dropdown from '@/components/Dropdown.vue';
|
|
120
104
|
import CustomDateRangePicker from '@/components/CustomDateRangePicker.vue';
|
|
121
|
-
import { callAdminForthApi } from '@/utils';
|
|
122
|
-
import { useRouter } from 'vue-router';
|
|
123
|
-
import { computedAsync } from '@vueuse/core'
|
|
124
|
-
import CustomRangePicker from "@/components/CustomRangePicker.vue";
|
|
125
|
-
import { useFiltersStore } from '@/stores/filters';
|
|
126
|
-
|
|
127
|
-
const filtersStore = useFiltersStore();
|
|
128
|
-
|
|
129
105
|
|
|
130
106
|
// props: columns
|
|
131
107
|
// add support for v-model:filers
|
|
132
108
|
const props = defineProps(['columns', 'filters', 'show', 'columnsMinMax']);
|
|
133
109
|
const emits = defineEmits(['update:filters', 'hide']);
|
|
134
110
|
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
const columnsWithFilter = computed(
|
|
111
|
+
const columnsWithFilter = computed(
|
|
139
112
|
() => props.columns?.filter(column => column.showIn.includes('filter')) || []
|
|
140
113
|
);
|
|
141
114
|
|
|
142
|
-
const columnOptions = computedAsync(async () => {
|
|
143
|
-
const ret = {};
|
|
144
|
-
if (!props.columns) {
|
|
145
|
-
return ret;
|
|
146
|
-
}
|
|
147
|
-
await Promise.all(
|
|
148
|
-
Object.values(props.columns).map(async (column) => {
|
|
149
|
-
if (column.foreignResource) {
|
|
150
|
-
const list = await callAdminForthApi({
|
|
151
|
-
method: 'POST',
|
|
152
|
-
path: `/get_resource_foreign_data`,
|
|
153
|
-
body: {
|
|
154
|
-
resourceId: router.currentRoute.value.params.resourceId,
|
|
155
|
-
column: column.name,
|
|
156
|
-
limit: 1000,
|
|
157
|
-
offset: 0,
|
|
158
|
-
},
|
|
159
|
-
});
|
|
160
|
-
ret[column.name] = list.items;
|
|
161
|
-
}
|
|
162
|
-
})
|
|
163
|
-
);
|
|
164
|
-
|
|
165
|
-
return ret;
|
|
166
|
-
}, {});
|
|
167
|
-
|
|
168
|
-
|
|
169
115
|
// sync 'body' class 'overflow-hidden' with show prop show
|
|
170
116
|
watch(() => props.show, (show) => {
|
|
171
117
|
if (show) {
|
|
@@ -184,39 +130,28 @@ watch(() => props.show, (show) => {
|
|
|
184
130
|
|
|
185
131
|
function setFilterItem({ column, operator, value }) {
|
|
186
132
|
|
|
187
|
-
const index =
|
|
133
|
+
const index = props.filters.findIndex(f => f.field === column.name && f.operator === operator);
|
|
188
134
|
if (value === undefined) {
|
|
189
135
|
if (index !== -1) {
|
|
190
|
-
|
|
136
|
+
props.filters.splice(index, 1);
|
|
191
137
|
}
|
|
138
|
+
emits('update:filters', [...props.filters]);
|
|
139
|
+
return;
|
|
192
140
|
} else {
|
|
193
141
|
if (index === -1) {
|
|
194
|
-
|
|
142
|
+
props.filters.push({ field: column.name, value, operator });
|
|
195
143
|
} else {
|
|
196
|
-
|
|
144
|
+
props.filters[index].value = value;
|
|
197
145
|
}
|
|
198
146
|
}
|
|
199
|
-
emits('update:filters', [...
|
|
147
|
+
emits('update:filters', [...props.filters]);
|
|
200
148
|
}
|
|
201
149
|
|
|
202
150
|
function getFilterItem({ column, operator }) {
|
|
203
|
-
return
|
|
151
|
+
return props.filters.find(f => f.field === column.name && f.operator === operator)?.value || '';
|
|
204
152
|
}
|
|
205
153
|
|
|
206
154
|
async function clear() {
|
|
207
|
-
|
|
208
|
-
emits('update:filters', [...filtersStore.filters]);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
function getFilterMinValue(columnName) {
|
|
212
|
-
if(props.columnsMinMax && props.columnsMinMax[columnName]) {
|
|
213
|
-
return props.columnsMinMax[columnName]?.min
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
function getFilterMaxValue(columnName) {
|
|
218
|
-
if(props.columnsMinMax && props.columnsMinMax[columnName]) {
|
|
219
|
-
return props.columnsMinMax[columnName]?.max
|
|
220
|
-
}
|
|
155
|
+
emits('update:filters', []);
|
|
221
156
|
}
|
|
222
157
|
</script>
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<RouterLink
|
|
3
3
|
:to="{name: item.resourceId ? 'resource-list' : item.path, params: item.resourceId ? { resourceId: item.resourceId }: {}}"
|
|
4
|
-
class="flex
|
|
4
|
+
class="flex items-center py-2 text-sm text-gray-700 hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-600 dark:hover:text-white" role="menuitem"
|
|
5
5
|
:class="{
|
|
6
6
|
'px-4': isChild,
|
|
7
7
|
'px-2': !isChild,
|
|
8
|
-
'bg-
|
|
8
|
+
'bg-blue-100 dark:bg-gray-700': item.resourceId ?
|
|
9
9
|
($route.params.resourceId === item.resourceId && $route.name === 'resource-list') :
|
|
10
10
|
($route.name === item.path)
|
|
11
11
|
}"
|
|
12
12
|
>
|
|
13
|
-
<component v-if="item.icon" :is="getIcon(item.icon)" class="w-5 h-5 text-
|
|
13
|
+
<component v-if="item.icon" :is="getIcon(item.icon)" class="w-5 h-5 text-gray-500 transition duration-75 dark:text-gray-400 group-hover:text-gray-900 dark:group-hover:text-white" ></component>
|
|
14
14
|
<span class="ms-3">{{ item.label }}</span>
|
|
15
15
|
</RouterLink>
|
|
16
16
|
</template>
|