adminforth 4.1.4 → 4.2.0
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,25 +1,26 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<nav class="flex items-center min-h-[2.25rem]" aria-label="Breadcrumb">
|
|
3
|
-
<ol class="
|
|
4
|
-
<li class="inline-flex items-center">
|
|
3
|
+
<ol class="flex min-w-0 items-center space-x-1 md:space-x-2 rtl:space-x-reverse">
|
|
4
|
+
<li class="inline-flex shrink-0 items-center">
|
|
5
5
|
<RouterLink :to="{name: 'home'}" class="inline-flex items-center text-sm text-lightBreadcrumbsHomepageText hover:text-lightBreadcrumbsHomepageTextHover dark:text-darkBreadcrumbsHomepageText dark:hover:text-darkBreadcrumbsHomepageTextHover">
|
|
6
|
-
<IconHouse class="w-3.5 h-3.5 me-1.5" aria-hidden="true" />
|
|
7
|
-
|
|
6
|
+
<IconHouse class="w-3.5 h-3.5 @lg/header:me-1.5" aria-hidden="true" />
|
|
7
|
+
<!-- a narrow header keeps only the house, the label stays for screen readers -->
|
|
8
|
+
<span class="sr-only @lg/header:not-sr-only">{{ $t('Home') }}</span>
|
|
8
9
|
</RouterLink>
|
|
9
10
|
</li>
|
|
10
|
-
<li>
|
|
11
|
+
<li class="min-w-0">
|
|
11
12
|
<div class="flex items-center">
|
|
12
|
-
<IconChevronRight class="rtl:rotate-180 w-3.5 h-3.5 text-lightBreadcrumbsArrowIcon dark:text-darkBreadcrumbsArrowIcon mx-0.5" aria-hidden="true" />
|
|
13
|
-
<RouterLink :to="{name: 'resource-list', params: { resourceId: $route.params.resourceId }}" class="md:ms-1"
|
|
13
|
+
<IconChevronRight class="shrink-0 rtl:rotate-180 w-3.5 h-3.5 text-lightBreadcrumbsArrowIcon dark:text-darkBreadcrumbsArrowIcon mx-0.5" aria-hidden="true" />
|
|
14
|
+
<RouterLink :to="{name: 'resource-list', params: { resourceId: $route.params.resourceId }}" class="md:ms-1 truncate"
|
|
14
15
|
:class="$route.params.primaryKey
|
|
15
16
|
? 'text-sm text-lightBreadcrumbsHomepageText hover:text-lightBreadcrumbsHomepageTextHover dark:text-darkBreadcrumbsHomepageText dark:hover:text-darkBreadcrumbsHomepageTextHover'
|
|
16
17
|
: 'text-xl leading-7 font-semibold tracking-tight text-lightBreadcrumbsText dark:text-darkBreadcrumbsText'">{{ coreStore.resourceById[$route.params.resourceId]?.label }}</RouterLink>
|
|
17
18
|
</div>
|
|
18
19
|
</li>
|
|
19
20
|
|
|
20
|
-
<li v-if="$route.params.primaryKey">
|
|
21
|
+
<li v-if="$route.params.primaryKey" class="min-w-0">
|
|
21
22
|
<div class="flex items-center">
|
|
22
|
-
<IconChevronRight class="rtl:rotate-180 w-3.5 h-3.5 text-lightBreadcrumbsArrowIcon dark:text-darkBreadcrumbsArrowIcon mx-0.5" aria-hidden="true" />
|
|
23
|
+
<IconChevronRight class="shrink-0 rtl:rotate-180 w-3.5 h-3.5 text-lightBreadcrumbsArrowIcon dark:text-darkBreadcrumbsArrowIcon mx-0.5" aria-hidden="true" />
|
|
23
24
|
<span class="ms-1 text-xl leading-7 font-semibold tracking-tight text-lightBreadcrumbsText md:ms-1 dark:text-darkBreadcrumbsText
|
|
24
25
|
max-w-80 truncate">
|
|
25
26
|
{{ $route.name === 'resource-edit' ? $t('Edit') : $t('Show') }} {{ coreStore.record?._label }}</span>
|
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
<div class="flex items-center gap-
|
|
6
|
-
|
|
3
|
+
<!-- the header follows its own width, not the viewport, because the sidebar and the agent panel squeeze it too -->
|
|
4
|
+
<div class="@container/header mb-4">
|
|
5
|
+
<div class="flex flex-wrap items-center gap-3">
|
|
6
|
+
<!-- a record title of show and edit takes the room it needs and the buttons go under it, a resource title gives way to the buttons -->
|
|
7
|
+
<Breadcrumbs :class="$route.params.primaryKey ? 'min-w-0 flex-auto' : 'min-w-24 flex-1'" />
|
|
8
|
+
<!-- filters take a full row under the title and the buttons, a wide header keeps all in one row -->
|
|
9
|
+
<div v-if="$slots.filters" class="order-last basis-full flex flex-wrap items-center gap-2 @4xl/header:order-none @4xl/header:basis-auto @4xl/header:ms-auto">
|
|
10
|
+
<slot name="filters"></slot>
|
|
11
|
+
</div>
|
|
12
|
+
<!-- actions for the checked rows get a row of their own above the table, so the buttons next to the title stay in place -->
|
|
13
|
+
<div v-if="$slots.selection" class="order-last basis-full flex flex-wrap items-center gap-2">
|
|
14
|
+
<slot name="selection"></slot>
|
|
15
|
+
</div>
|
|
16
|
+
<div class="flex items-center gap-2 flex-wrap">
|
|
17
|
+
<slot></slot>
|
|
18
|
+
</div>
|
|
7
19
|
</div>
|
|
8
20
|
</div>
|
|
9
21
|
<div v-if="coreStore.resourceColumnsError" >
|
|
@@ -13,12 +25,12 @@
|
|
|
13
25
|
|
|
14
26
|
</template>
|
|
15
27
|
|
|
16
|
-
<script setup>
|
|
17
|
-
import Breadcrumbs from '@/components/Breadcrumbs.vue';
|
|
28
|
+
<script setup lang="ts">
|
|
29
|
+
import Breadcrumbs from '@/components/Breadcrumbs.vue';
|
|
18
30
|
import PageNotFound from '@/views/PageNotFound.vue';
|
|
19
31
|
|
|
20
32
|
import { useCoreStore } from '@/stores/core';
|
|
21
33
|
|
|
22
34
|
const coreStore = useCoreStore();
|
|
23
35
|
|
|
24
|
-
</script>
|
|
36
|
+
</script>
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
/>
|
|
22
22
|
|
|
23
23
|
<BreadcrumbsWithButtons>
|
|
24
|
-
<template v-if="isResourceReady">
|
|
24
|
+
<template v-if="isResourceReady && beforeActionButtons.length" #filters>
|
|
25
25
|
<component
|
|
26
|
-
v-for="c in
|
|
26
|
+
v-for="c in beforeActionButtons"
|
|
27
27
|
:is="getCustomComponent(formatComponent(c))"
|
|
28
28
|
:meta="(c as AdminForthComponentDeclarationFull).meta"
|
|
29
29
|
:resource="coreStore.resource"
|
|
@@ -31,9 +31,10 @@
|
|
|
31
31
|
:checkboxes="checkboxes"
|
|
32
32
|
:clearCheckboxes="clearCheckboxes"
|
|
33
33
|
/>
|
|
34
|
+
</template>
|
|
35
|
+
<template v-if="isResourceReady && checkboxes.length" #selection>
|
|
34
36
|
<Button
|
|
35
37
|
@click="()=>{checkboxes = []}"
|
|
36
|
-
v-if="checkboxes.length"
|
|
37
38
|
data-tooltip-target="tooltip-remove-all"
|
|
38
39
|
variant="secondary"
|
|
39
40
|
iconOnly
|
|
@@ -47,11 +48,9 @@
|
|
|
47
48
|
</Button>
|
|
48
49
|
|
|
49
50
|
<div
|
|
50
|
-
v-
|
|
51
|
-
v-for="(action,i) in coreStore.resource?.options?.bulkActions"
|
|
51
|
+
v-for="(action,i) in coreStore.resource?.options?.bulkActions?.filter(a => !a.showInThreeDotsDropdown)"
|
|
52
52
|
>
|
|
53
53
|
<Button
|
|
54
|
-
v-if="!action.showInThreeDotsDropdown"
|
|
55
54
|
:key="action.id"
|
|
56
55
|
@click="startBulkActionInner(action.id!)"
|
|
57
56
|
class="h-[2.125rem] px-2.5"
|
|
@@ -73,7 +72,6 @@
|
|
|
73
72
|
</Button>
|
|
74
73
|
</div>
|
|
75
74
|
<div
|
|
76
|
-
v-if="checkboxes.length"
|
|
77
75
|
v-for="(action,i) in coreStore.resource?.options?.actions?.filter(a => a.showIn?.bulkButton)"
|
|
78
76
|
>
|
|
79
77
|
<Button
|
|
@@ -93,7 +91,8 @@
|
|
|
93
91
|
{{ `${action.name} (${checkboxes.length})` }}
|
|
94
92
|
</Button>
|
|
95
93
|
</div>
|
|
96
|
-
|
|
94
|
+
</template>
|
|
95
|
+
<template v-if="isResourceReady">
|
|
97
96
|
<LinkButton v-if="coreStore.resource?.options?.allowedActions?.create"
|
|
98
97
|
:to="{ name: 'resource-create', params: { resourceId: $route.params.resourceId } }"
|
|
99
98
|
class="af-create-button h-[2.125rem] px-2.5"
|
|
@@ -103,13 +102,14 @@
|
|
|
103
102
|
</LinkButton>
|
|
104
103
|
|
|
105
104
|
<Button
|
|
106
|
-
class="af-filter-button h-[2.125rem] px-
|
|
105
|
+
class="af-filter-button h-[2.125rem] px-2 py-3 @lg/header:px-3"
|
|
107
106
|
@click="()=>{filtersShow = !filtersShow}"
|
|
108
107
|
v-if="coreStore.resource?.options?.allowedActions?.filter"
|
|
109
108
|
variant="secondary"
|
|
110
109
|
>
|
|
111
110
|
<IconListFilter class="w-4 h-4"/>
|
|
112
|
-
|
|
111
|
+
<!-- a narrow header keeps only the icon, the label stays for screen readers -->
|
|
112
|
+
<span class="sr-only @lg/header:not-sr-only">{{ $t('Filter') }}</span>
|
|
113
113
|
<div v-if="filtersStore.visibleFiltersCount" class="flex items-center gap-1 ms-1">
|
|
114
114
|
<span class="inline-flex items-center justify-center min-w-[1.125rem] h-[1.125rem] px-1 rounded-full text-[11px] font-semibold tabular-nums bg-lightPrimary text-lightPrimaryContrast dark:bg-darkPrimary dark:text-darkPrimaryContrast">
|
|
115
115
|
{{ filtersStore.visibleFiltersCount }}
|
|
@@ -232,6 +232,7 @@ const route = useRoute();
|
|
|
232
232
|
|
|
233
233
|
// previous resource stays in the store until the new one is applied, its injections must not render here
|
|
234
234
|
const isResourceReady = computed(() => coreStore.resource?.resourceId === route.params.resourceId);
|
|
235
|
+
const beforeActionButtons = computed(() => (coreStore.resourceOptions?.pageInjections?.list?.beforeActionButtons || []) as AdminForthComponentDeclaration[]);
|
|
235
236
|
|
|
236
237
|
const page = ref(1);
|
|
237
238
|
const columnsMinMax = ref({});
|