adminforth 3.35.1 → 4.0.1
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/codeInjector.d.ts.map +1 -1
- package/dist/modules/codeInjector.js +20 -3
- package/dist/modules/codeInjector.js.map +1 -1
- package/dist/modules/styleGenerator.d.ts +13 -0
- package/dist/modules/styleGenerator.d.ts.map +1 -1
- package/dist/modules/styleGenerator.js +274 -1
- package/dist/modules/styleGenerator.js.map +1 -1
- package/dist/modules/styles.d.ts +24 -0
- package/dist/modules/styles.d.ts.map +1 -1
- package/dist/modules/styles.js +452 -427
- package/dist/modules/styles.js.map +1 -1
- package/dist/modules/utils.d.ts +1 -13
- package/dist/modules/utils.d.ts.map +1 -1
- package/dist/modules/utils.js +2 -275
- package/dist/modules/utils.js.map +1 -1
- package/dist/spa/index.html +2 -2
- package/dist/spa/package-lock.json +1373 -1136
- package/dist/spa/package.json +18 -15
- package/dist/spa/pnpm-lock.yaml +1067 -648
- package/dist/spa/src/App.vue +84 -92
- package/dist/spa/src/afcl/AreaChart.vue +8 -24
- package/dist/spa/src/afcl/BarChart.vue +8 -23
- package/dist/spa/src/afcl/Button.vue +8 -2
- package/dist/spa/src/afcl/ButtonGroup.vue +9 -9
- package/dist/spa/src/afcl/Card.vue +40 -19
- package/dist/spa/src/afcl/Checkbox.vue +6 -6
- package/dist/spa/src/afcl/CountryFlag.vue +17 -11
- package/dist/spa/src/afcl/DatePicker.vue +7 -7
- package/dist/spa/src/afcl/Dialog.vue +8 -9
- package/dist/spa/src/afcl/DropdownMenu.vue +210 -0
- package/dist/spa/src/afcl/DropdownMenuAccordion.vue +56 -0
- package/dist/spa/src/afcl/DropdownMenuItem.vue +86 -0
- package/dist/spa/src/afcl/Dropzone.vue +10 -26
- package/dist/spa/src/afcl/Input.vue +4 -4
- package/dist/spa/src/afcl/Link.vue +1 -1
- package/dist/spa/src/afcl/LinkButton.vue +15 -1
- package/dist/spa/src/afcl/MixedChart.vue +4 -18
- package/dist/spa/src/afcl/Modal.vue +9 -9
- package/dist/spa/src/afcl/PieChart.vue +8 -29
- package/dist/spa/src/afcl/ProgressBar.vue +2 -2
- package/dist/spa/src/afcl/Select.vue +20 -20
- package/dist/spa/src/afcl/Skeleton.vue +1 -1
- package/dist/spa/src/afcl/Spinner.vue +1 -1
- package/dist/spa/src/afcl/Table.vue +19 -26
- package/dist/spa/src/afcl/Textarea.vue +1 -1
- package/dist/spa/src/afcl/Toggle.vue +4 -4
- package/dist/spa/src/afcl/Tooltip.vue +1 -1
- package/dist/spa/src/afcl/TreeMapChart.vue +5 -20
- package/dist/spa/src/afcl/VerticalTabs.vue +4 -4
- package/dist/spa/src/afcl/buttonStyles.ts +73 -33
- package/dist/spa/src/afcl/chartUtils.ts +19 -0
- package/dist/spa/src/afcl/classMerge.ts +11 -0
- package/dist/spa/src/afcl/dropdownMenuContext.ts +10 -0
- package/dist/spa/src/afcl/fileSize.ts +12 -0
- package/dist/spa/src/afcl/index.ts +3 -0
- package/dist/spa/src/components/AcceptModal.vue +17 -19
- package/dist/spa/src/components/Breadcrumbs.vue +11 -13
- package/dist/spa/src/components/BreadcrumbsWithButtons.vue +2 -2
- package/dist/spa/src/components/CallActionWrapper.vue +3 -0
- package/dist/spa/src/components/ColumnValueInput.vue +5 -5
- package/dist/spa/src/components/ColumnValueInputWrapper.vue +7 -6
- package/dist/spa/src/components/CustomDateRangePicker.vue +8 -8
- package/dist/spa/src/components/CustomRangePicker.vue +2 -2
- package/dist/spa/src/components/ErrorMessage.vue +3 -4
- package/dist/spa/src/components/Filters.vue +13 -13
- package/dist/spa/src/components/GroupsTable.vue +12 -12
- package/dist/spa/src/components/ListActionsThreeDots.vue +89 -207
- package/dist/spa/src/components/MenuLink.vue +23 -20
- package/dist/spa/src/components/RangePicker.vue +9 -10
- package/dist/spa/src/components/ResourceListTable.vue +68 -65
- package/dist/spa/src/components/ShowTable.vue +8 -8
- package/dist/spa/src/components/Sidebar.vue +31 -38
- package/dist/spa/src/components/ThreeDotsMenu.vue +88 -136
- package/dist/spa/src/components/Toast.vue +16 -23
- package/dist/spa/src/components/UserMenuSettingsButton.vue +15 -36
- package/dist/spa/src/components/ValueRenderer.vue +13 -8
- package/dist/spa/src/components/icons/IconCalendar.vue +3 -3
- package/dist/spa/src/components/icons/IconTime.vue +3 -3
- package/dist/spa/src/index.scss +6 -2
- package/dist/spa/src/main.ts +2 -0
- package/dist/spa/src/renderers/CompactField.vue +3 -3
- package/dist/spa/src/renderers/CompactUUID.vue +3 -3
- package/dist/spa/src/renderers/SensitiveBlurCell.vue +9 -9
- package/dist/spa/src/utils/threeDotsMenu.ts +7 -0
- package/dist/spa/src/utils/userMenu.ts +5 -0
- package/dist/spa/src/utils/utils.ts +12 -39
- package/dist/spa/src/views/CreateEditSkeleton.vue +3 -3
- package/dist/spa/src/views/CreateView.vue +5 -6
- package/dist/spa/src/views/EditView.vue +5 -6
- package/dist/spa/src/views/ListView.vue +114 -115
- package/dist/spa/src/views/LoginView.vue +4 -4
- package/dist/spa/src/views/ShowView.vue +17 -18
- package/dist/spa/vite.config.ts +23 -16
- package/package.json +1 -2
|
@@ -1,70 +1,110 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const twMerge = extendTailwindMerge({
|
|
6
|
-
extend: {
|
|
7
|
-
classGroups: {
|
|
8
|
-
rounded: [{ rounded: ['default'] }],
|
|
9
|
-
},
|
|
10
|
-
},
|
|
11
|
-
});
|
|
1
|
+
import { type ClassNameValue } from 'tailwind-merge';
|
|
2
|
+
import { mergeClasses } from './classMerge';
|
|
3
|
+
|
|
4
|
+
export type ButtonVariant = 'primary' | 'secondary' | 'danger' | 'ghost';
|
|
12
5
|
|
|
13
|
-
export type
|
|
6
|
+
export type ButtonSize = 'md' | 'sm';
|
|
14
7
|
|
|
15
8
|
export const buttonBaseStyles = `
|
|
16
9
|
flex items-center justify-center
|
|
17
|
-
gap-1 border focus:ring-
|
|
18
|
-
|
|
19
|
-
text-sm px-5 py-
|
|
10
|
+
gap-1.5 border focus-visible:ring-[3px] focus:outline-none
|
|
11
|
+
font-medium rounded-default whitespace-nowrap
|
|
12
|
+
text-sm leading-5 px-3.5 py-1.5 text-center transition-colors duration-150
|
|
20
13
|
`;
|
|
21
14
|
|
|
22
|
-
|
|
15
|
+
const variantStyles: Record<ButtonVariant, string> = {
|
|
23
16
|
primary: `
|
|
24
17
|
text-lightButtonsText bg-lightButtonsBackground border-lightButtonsBorder
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
dark:
|
|
28
|
-
dark:
|
|
29
|
-
dark:hover:border-darkButtonsBorderHover
|
|
18
|
+
focus-visible:ring-lightButtonFocusRing
|
|
19
|
+
|
|
20
|
+
dark:text-darkButtonsText dark:bg-darkButtonsBackground dark:border-darkButtonsBorder
|
|
21
|
+
dark:focus-visible:ring-darkButtonFocusRing
|
|
30
22
|
`,
|
|
31
23
|
|
|
32
24
|
secondary: `
|
|
33
|
-
text-lightSecondaryContrast/90 bg-lightSecondary border-lightSecondaryContrast/
|
|
34
|
-
|
|
25
|
+
text-lightSecondaryContrast/90 bg-lightSecondary border-lightSecondaryContrast/[0.17]
|
|
26
|
+
focus-visible:ring-lightFocusRing
|
|
35
27
|
|
|
36
|
-
dark:
|
|
37
|
-
dark:
|
|
38
|
-
dark:hover:text-white
|
|
28
|
+
dark:text-darkSecondaryContrast/80 dark:bg-darkSecondary dark:border-darkSecondaryContrast/[0.17]
|
|
29
|
+
dark:focus-visible:ring-darkFocusRing
|
|
39
30
|
`,
|
|
40
31
|
|
|
41
32
|
danger: `
|
|
42
33
|
text-lightAcceptModalConfirmButtonText dark:text-darkAcceptModalConfirmButtonText
|
|
43
34
|
bg-lightAcceptModalConfirmButtonBackground dark:bg-darkAcceptModalConfirmButtonBackground
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
35
|
+
focus-visible:ring-lightAcceptModalConfirmButtonFocus dark:focus-visible:ring-darkAcceptModalConfirmButtonFocus
|
|
36
|
+
border-transparent
|
|
37
|
+
`,
|
|
38
|
+
|
|
39
|
+
ghost: `
|
|
40
|
+
bg-transparent border-transparent text-lightInputIconColor focus-visible:ring-lightFocusRing
|
|
41
|
+
dark:text-darkInputIconColor dark:focus-visible:ring-darkFocusRing
|
|
47
42
|
`,
|
|
48
43
|
};
|
|
49
44
|
|
|
45
|
+
// kept apart so a disabled button gets no hover feedback
|
|
46
|
+
const variantHoverStyles: Record<ButtonVariant, string> = {
|
|
47
|
+
primary: `
|
|
48
|
+
hover:bg-lightButtonsHover hover:border-lightButtonsBorderHover
|
|
49
|
+
dark:hover:bg-darkButtonsHover dark:hover:border-darkButtonsBorderHover
|
|
50
|
+
`,
|
|
51
|
+
secondary: `
|
|
52
|
+
hover:bg-lightSecondaryDarken hover:text-lightSecondaryContrast
|
|
53
|
+
dark:hover:bg-darkSecondaryLighten dark:hover:text-darkSecondaryContrast
|
|
54
|
+
`,
|
|
55
|
+
danger: `
|
|
56
|
+
hover:bg-lightAcceptModalConfirmButtonBackgroundHover hover:border-transparent
|
|
57
|
+
dark:hover:bg-darkAcceptModalConfirmButtonBackgroundHover
|
|
58
|
+
`,
|
|
59
|
+
ghost: `
|
|
60
|
+
hover:bg-lightSecondaryDarken hover:text-lightInputText
|
|
61
|
+
dark:hover:bg-darkSecondaryLighten dark:hover:text-darkInputText
|
|
62
|
+
`,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// public styles of an enabled button, for apps which style their own elements as AFCL buttons
|
|
66
|
+
export const buttonVariantStyles = Object.fromEntries(
|
|
67
|
+
Object.entries(variantStyles).map(([variant, styles]) => [variant, `${styles} ${variantHoverStyles[variant as ButtonVariant]}`]),
|
|
68
|
+
) as Record<ButtonVariant, string>;
|
|
69
|
+
|
|
70
|
+
// md is the base size, its height comes from the padding and line height of the label
|
|
71
|
+
export const buttonSizeStyles: Record<ButtonSize, string> = {
|
|
72
|
+
md: '',
|
|
73
|
+
sm: 'h-7 py-0 px-2.5 text-xs',
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// a square button with one icon in the slot
|
|
77
|
+
export const buttonIconOnlyStyles: Record<ButtonSize, string> = {
|
|
78
|
+
md: 'h-[2.125rem] w-[2.125rem] shrink-0 p-0 [&>svg]:w-4 [&>svg]:h-4',
|
|
79
|
+
sm: 'w-7 shrink-0 p-0 [&>svg]:w-4 [&>svg]:h-4',
|
|
80
|
+
};
|
|
81
|
+
|
|
50
82
|
export const buttonActiveStyles = 'active brightness-200 hover:brightness-150';
|
|
51
83
|
|
|
52
|
-
export const buttonDisabledStyles = 'cursor-
|
|
84
|
+
export const buttonDisabledStyles = 'cursor-not-allowed opacity-50';
|
|
53
85
|
|
|
54
86
|
|
|
55
87
|
export function getButtonClasses(
|
|
56
88
|
options: {
|
|
57
89
|
variant?: ButtonVariant;
|
|
90
|
+
size?: ButtonSize;
|
|
91
|
+
iconOnly?: boolean;
|
|
58
92
|
shadow?: boolean;
|
|
59
93
|
active?: boolean;
|
|
60
94
|
disabled?: boolean;
|
|
61
95
|
},
|
|
62
96
|
...extraClasses: ClassNameValue[]
|
|
63
97
|
): string {
|
|
64
|
-
|
|
98
|
+
const variant = options.variant ?? 'primary';
|
|
99
|
+
const size = options.size ?? 'md';
|
|
100
|
+
return mergeClasses(
|
|
65
101
|
buttonBaseStyles,
|
|
66
|
-
|
|
67
|
-
options.
|
|
102
|
+
variantStyles[variant],
|
|
103
|
+
!options.disabled && variantHoverStyles[variant],
|
|
104
|
+
buttonSizeStyles[size],
|
|
105
|
+
options.iconOnly && buttonIconOnlyStyles[size],
|
|
106
|
+
// ghost has no surface to lift
|
|
107
|
+
options.shadow && variant !== 'ghost' && 'af-button-shadow',
|
|
68
108
|
options.active && buttonActiveStyles,
|
|
69
109
|
options.disabled && buttonDisabledStyles,
|
|
70
110
|
...extraClasses,
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// categorical slots in fixed order, the first five are the chart palette drawn in design/system.html
|
|
2
|
+
export const CHART_COLORS = [
|
|
3
|
+
"#2a78d6", "#eb6834", "#1baf7a", "#eda100", "#e87ba4", "#008300", "#6250d6", "#e34948",
|
|
4
|
+
"#4E79A7", "#F28E2B", "#E15759", "#76B7B2", "#59A14F", "#EDC949", "#B07AA1", "#FF9DA6", "#9C755F", "#BAB0AC",
|
|
5
|
+
"#2B8A86", "#CC4D58", "#F7941D", "#F9C232", "#729B33", "#497288", "#16578D", "#5F4D99", "#F9F871", "#F9F871",
|
|
6
|
+
];
|
|
7
|
+
|
|
8
|
+
// merges ApexCharts options on the lowest level ({ chart: { height } } keeps the rest of chart),
|
|
9
|
+
// every touched level is copied so the shared base options of a component are never mutated
|
|
10
|
+
export function mergeChartOptions(options: any, overrides: any) {
|
|
11
|
+
for (const key in overrides) {
|
|
12
|
+
if (typeof overrides[key] === 'object' && !Array.isArray(overrides[key])) {
|
|
13
|
+
options[key] = { ...options[key] };
|
|
14
|
+
mergeChartOptions(options[key], overrides[key]);
|
|
15
|
+
} else {
|
|
16
|
+
options[key] = overrides[key];
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { extendTailwindMerge } from 'tailwind-merge';
|
|
2
|
+
|
|
3
|
+
// `rounded-default` comes from the themable borderRadius.default token, tailwind-merge does not
|
|
4
|
+
// know it out of the box and would not treat it as conflicting with rounded-* passed from outside
|
|
5
|
+
export const mergeClasses = extendTailwindMerge({
|
|
6
|
+
extend: {
|
|
7
|
+
classGroups: {
|
|
8
|
+
rounded: [{ rounded: ['default'] }],
|
|
9
|
+
},
|
|
10
|
+
},
|
|
11
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { InjectionKey } from 'vue';
|
|
2
|
+
|
|
3
|
+
export type DropdownMenuPlacement = 'bottom-start' | 'bottom-end' | 'left-start' | 'right-start';
|
|
4
|
+
|
|
5
|
+
export interface DropdownMenuContext {
|
|
6
|
+
// called by DropdownMenuItem after its click handlers ran
|
|
7
|
+
itemSelected: () => void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const DROPDOWN_MENU_KEY: InjectionKey<DropdownMenuContext> = Symbol('afcl-dropdown-menu');
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function humanifySize(size: number) {
|
|
2
|
+
if (!size) {
|
|
3
|
+
return '';
|
|
4
|
+
}
|
|
5
|
+
const units = ['B', 'KB', 'MB', 'GB', 'TB']
|
|
6
|
+
let i = 0
|
|
7
|
+
while (size >= 1024 && i < units.length - 1) {
|
|
8
|
+
size /= 1024
|
|
9
|
+
i++
|
|
10
|
+
}
|
|
11
|
+
return `${size.toFixed(1)} ${units[i]}`
|
|
12
|
+
}
|
|
@@ -27,4 +27,7 @@ export { default as Textarea } from './Textarea.vue';
|
|
|
27
27
|
export { default as ButtonGroup } from './ButtonGroup.vue';
|
|
28
28
|
export { default as Card } from './Card.vue';
|
|
29
29
|
export { default as Modal } from './Modal.vue';
|
|
30
|
+
export { default as DropdownMenu } from './DropdownMenu.vue';
|
|
31
|
+
export { default as DropdownMenuItem } from './DropdownMenuItem.vue';
|
|
32
|
+
export { default as DropdownMenuAccordion } from './DropdownMenuAccordion.vue';
|
|
30
33
|
export { buttonBaseStyles, buttonVariantStyles } from './buttonStyles.js';
|
|
@@ -6,39 +6,37 @@
|
|
|
6
6
|
backgroundCustomClasses="z-[998]"
|
|
7
7
|
modalCustomClasses="z-[999] flex items-center justify-center"
|
|
8
8
|
>
|
|
9
|
-
<div class="relative p-6 sm:
|
|
9
|
+
<div class="relative p-6 sm:w-[420px] rounded-xl shadow-popover dark:shadow-darkPopover bg-lightAcceptModalBackground dark:bg-darkAcceptModalBackground" >
|
|
10
10
|
|
|
11
|
-
<button type="button" @click="modalStore.togleModal()" class="absolute top-
|
|
12
|
-
<
|
|
13
|
-
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/>
|
|
14
|
-
</svg>
|
|
11
|
+
<button type="button" @click="modalStore.togleModal()" class="absolute top-3 right-3 p-1.5 rounded-default text-lightAcceptModalCloseIcon hover:text-lightAcceptModalCloseIconHover hover:bg-lightAcceptModalCloseIconHoverBackground dark:text-darkAcceptModalCloseIcon dark:hover:text-darkAcceptModalCloseIconHover dark:hover:bg-darkAcceptModalCloseIconHoverBackground transition-colors" >
|
|
12
|
+
<IconX class="w-4 h-4" />
|
|
15
13
|
</button>
|
|
16
14
|
|
|
17
15
|
<div class="text-center flex flex-col">
|
|
18
|
-
<div class="mx-auto flex items-center justify-center h-
|
|
19
|
-
:class="modalStore.modalContent.dangerous ? 'bg-
|
|
20
|
-
<
|
|
21
|
-
:class="modalStore.modalContent.dangerous ? 'text-
|
|
22
|
-
<div class="absolute bottom-1 right-1 rounded-
|
|
23
|
-
:class="modalStore.modalContent.dangerous ? 'bg-
|
|
16
|
+
<div class="mx-auto flex items-center justify-center h-12 w-12 rounded-xl mb-4 relative"
|
|
17
|
+
:class="modalStore.modalContent.dangerous ? 'bg-lightDangerSoft dark:bg-darkDangerSoft' : 'bg-lightSecondaryDarken dark:bg-darkSecondaryLighten'">
|
|
18
|
+
<IconClipboardList class="w-6 h-6"
|
|
19
|
+
:class="modalStore.modalContent.dangerous ? 'text-lightAcceptModalWarningIcon dark:text-darkAcceptModalWarningIcon' : 'text-lightButtonsBackground dark:text-darkButtonsBackground'" />
|
|
20
|
+
<div class="absolute -bottom-1 -right-1 rounded-full w-[18px] h-[18px] flex items-center justify-center border-2 border-lightAcceptModalBackground dark:border-darkAcceptModalBackground"
|
|
21
|
+
:class="modalStore.modalContent.dangerous ? 'bg-lightAcceptModalConfirmButtonBackground dark:bg-darkAcceptModalConfirmButtonBackground' : 'bg-lightButtonsBackground dark:bg-darkButtonsBackground'">
|
|
24
22
|
<span class="text-lightButtonsText dark:text-darkButtonsText text-[10px] font-medium">!</span>
|
|
25
23
|
</div>
|
|
26
24
|
</div>
|
|
27
25
|
|
|
28
26
|
<div class="flex flex-col gap-3">
|
|
29
|
-
<h3 v-if="modalStore?.modalContent?.title" class="text-
|
|
27
|
+
<h3 v-if="modalStore?.modalContent?.title" class="text-lg font-semibold tracking-tight text-lightDialogHeaderText dark:text-darkDialogHeaderText">
|
|
30
28
|
{{ modalStore.modalContent.title }}
|
|
31
29
|
</h3>
|
|
32
30
|
|
|
33
|
-
<div class="text-
|
|
34
|
-
<div v-if="modalStore?.modalContent?.contentHTML"
|
|
35
|
-
<p v-else-if="modalStore?.modalContent?.content"
|
|
31
|
+
<div class="text-sm text-lightAcceptModalText dark:text-darkAcceptModalText">
|
|
32
|
+
<div v-if="modalStore?.modalContent?.contentHTML" v-html="modalStore.modalContent.contentHTML"></div>
|
|
33
|
+
<p v-else-if="modalStore?.modalContent?.content">{{ modalStore.modalContent.content }}</p>
|
|
36
34
|
</div>
|
|
37
35
|
</div>
|
|
38
36
|
|
|
39
|
-
<hr class="border-t
|
|
37
|
+
<hr class="border-t border-lightDialogBreakLine dark:border-darkDialogBreakLine my-5">
|
|
40
38
|
|
|
41
|
-
<div class="flex justify-center gap-
|
|
39
|
+
<div class="flex justify-center gap-2 w-full">
|
|
42
40
|
<Button @click="()=>{modalStore.onAcceptFunction(false);modalStore.togleModal()}" type="button" variant="secondary" class="flex-1">
|
|
43
41
|
{{ modalStore?.modalContent?.cancelText }}
|
|
44
42
|
</Button>
|
|
@@ -52,7 +50,7 @@
|
|
|
52
50
|
</Button>
|
|
53
51
|
</div>
|
|
54
52
|
|
|
55
|
-
<div v-if="modalStore?.modalContent?.guardMessage" class="flex items-center justify-center mt-
|
|
53
|
+
<div v-if="modalStore?.modalContent?.guardMessage" class="flex items-center justify-center mt-5 text-xs text-lightAcceptModalText dark:text-darkAcceptModalText gap-1.5 font-medium">
|
|
56
54
|
<IconShieldCheck class="w-4 h-4" />
|
|
57
55
|
<span> {{ modalStore?.modalContent?.guardMessage }}</span>
|
|
58
56
|
</div>
|
|
@@ -67,7 +65,7 @@
|
|
|
67
65
|
import { watch, ref } from 'vue';
|
|
68
66
|
import { useModalStore } from '@/stores/modal';
|
|
69
67
|
import { Button, Modal } from '@/afcl';
|
|
70
|
-
import {
|
|
68
|
+
import { IconClipboardList, IconShieldCheck, IconX } from '@iconify-prerendered/vue-lucide';
|
|
71
69
|
|
|
72
70
|
|
|
73
71
|
const modalRef = ref();
|
|
@@ -1,29 +1,26 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<nav class="flex" aria-label="Breadcrumb">
|
|
2
|
+
<nav class="flex items-center min-h-[2.25rem]" aria-label="Breadcrumb">
|
|
3
3
|
<ol class="inline-flex items-center space-x-1 md:space-x-2 rtl:space-x-reverse flex-wrap">
|
|
4
4
|
<li class="inline-flex items-center">
|
|
5
|
-
<RouterLink :to="{name: 'home'}" class="inline-flex items-center text-sm
|
|
6
|
-
<
|
|
7
|
-
<path d="m19.707 9.293-2-2-7-7a1 1 0 0 0-1.414 0l-7 7-2 2a1 1 0 0 0 1.414 1.414L2 10.414V18a2 2 0 0 0 2 2h3a1 1 0 0 0 1-1v-4a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v4a1 1 0 0 0 1 1h3a2 2 0 0 0 2-2v-7.586l.293.293a1 1 0 0 0 1.414-1.414Z"/>
|
|
8
|
-
</svg>
|
|
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" />
|
|
9
7
|
{{ $t('Home') }}
|
|
10
8
|
</RouterLink>
|
|
11
9
|
</li>
|
|
12
10
|
<li>
|
|
13
11
|
<div class="flex items-center">
|
|
14
|
-
<
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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"
|
|
14
|
+
:class="$route.params.primaryKey
|
|
15
|
+
? 'text-sm text-lightBreadcrumbsHomepageText hover:text-lightBreadcrumbsHomepageTextHover dark:text-darkBreadcrumbsHomepageText dark:hover:text-darkBreadcrumbsHomepageTextHover'
|
|
16
|
+
: 'text-xl leading-7 font-semibold tracking-tight text-lightBreadcrumbsText dark:text-darkBreadcrumbsText'">{{ coreStore.resourceById[$route.params.resourceId]?.label }}</RouterLink>
|
|
18
17
|
</div>
|
|
19
18
|
</li>
|
|
20
19
|
|
|
21
20
|
<li v-if="$route.params.primaryKey">
|
|
22
21
|
<div class="flex items-center">
|
|
23
|
-
<
|
|
24
|
-
|
|
25
|
-
</svg>
|
|
26
|
-
<span class="ms-1 text-sm font-medium text-lightBreadcrumbsText md:ms-2 dark:text-darkBreadcrumbsText
|
|
22
|
+
<IconChevronRight class="rtl:rotate-180 w-3.5 h-3.5 text-lightBreadcrumbsArrowIcon dark:text-darkBreadcrumbsArrowIcon mx-0.5" aria-hidden="true" />
|
|
23
|
+
<span class="ms-1 text-xl leading-7 font-semibold tracking-tight text-lightBreadcrumbsText md:ms-1 dark:text-darkBreadcrumbsText
|
|
27
24
|
max-w-80 truncate">
|
|
28
25
|
{{ $route.name === 'resource-edit' ? $t('Edit') : $t('Show') }} {{ coreStore.record?._label }}</span>
|
|
29
26
|
</div>
|
|
@@ -36,6 +33,7 @@
|
|
|
36
33
|
|
|
37
34
|
<script setup>
|
|
38
35
|
import { useCoreStore } from '@/stores/core';
|
|
36
|
+
import { IconHouse, IconChevronRight } from '@iconify-prerendered/vue-lucide';
|
|
39
37
|
|
|
40
38
|
const coreStore = useCoreStore()
|
|
41
39
|
</script>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
|
-
<div class="flex items-center justify-between mb-
|
|
3
|
+
<div class="flex items-center justify-between mb-4 flex-wrap gap-y-2 gap-2">
|
|
4
4
|
<Breadcrumbs />
|
|
5
|
-
<div class="flex items-center
|
|
5
|
+
<div class="flex items-center gap-2 flex-wrap gap-y-1">
|
|
6
6
|
<slot></slot>
|
|
7
7
|
</div>
|
|
8
8
|
</div>
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
disableTogleOfSelectedItem
|
|
37
37
|
>
|
|
38
38
|
<template #extra-item v-if="columnLoadingState && columnLoadingState[column.name]?.loading">
|
|
39
|
-
<div class="text-center text-
|
|
39
|
+
<div class="text-center text-lightDropdownButtonsPlaceholderText dark:text-darkDropdownButtonsPlaceholderText py-2 flex items-center justify-center gap-2">
|
|
40
40
|
<Spinner class="w-4 h-4" />
|
|
41
41
|
{{ $t('Loading...') }}
|
|
42
42
|
</div>
|
|
@@ -157,7 +157,7 @@
|
|
|
157
157
|
class="h-6 inset-y-2 right-0 flex items-center px-2 pt-4 z-index-100 focus:outline-none"
|
|
158
158
|
@click="$emit('delete')"
|
|
159
159
|
>
|
|
160
|
-
<
|
|
160
|
+
<IconTrash2 class="w-4 h-4 text-lightInputIconColor hover:text-lightInputText dark:text-darkInputIconColor dark:hover:text-darkInputText"/>
|
|
161
161
|
</button>
|
|
162
162
|
<button
|
|
163
163
|
v-else-if="column.masked"
|
|
@@ -165,14 +165,14 @@
|
|
|
165
165
|
@click="$emit('update:unmasked')"
|
|
166
166
|
class="h-6 inset-y-2 right-0 flex items-center px-2 pt-4 z-index-100 focus:outline-none"
|
|
167
167
|
>
|
|
168
|
-
<
|
|
169
|
-
<
|
|
168
|
+
<IconEye class="w-4 h-4 text-lightInputIconColor hover:text-lightInputText dark:text-darkInputIconColor dark:hover:text-darkInputText" v-if="!unmasked[column.name]"/>
|
|
169
|
+
<IconEyeOff class="w-4 h-4 text-lightInputIconColor hover:text-lightInputText dark:text-darkInputIconColor dark:hover:text-darkInputText" v-else />
|
|
170
170
|
</button>
|
|
171
171
|
</div>
|
|
172
172
|
</template>
|
|
173
173
|
|
|
174
174
|
<script setup lang="ts">
|
|
175
|
-
import {
|
|
175
|
+
import { IconEyeOff, IconEye, IconTrash2 } from '@iconify-prerendered/vue-lucide';
|
|
176
176
|
import DatePicker from "@/afcl/DatePicker.vue";
|
|
177
177
|
import Select from '@/afcl/Select.vue';
|
|
178
178
|
import Input from '@/afcl/Input.vue';
|
|
@@ -27,11 +27,12 @@
|
|
|
27
27
|
<Button
|
|
28
28
|
v-if="!column.editReadonly"
|
|
29
29
|
type="button"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
variant="secondary"
|
|
31
|
+
class="me-2"
|
|
32
|
+
:class="{'mt-2': currentValues[column.name].length}"
|
|
33
|
+
@click="addArrayItem"
|
|
34
|
+
>
|
|
35
|
+
<IconPlus class="w-4 h-4"/>
|
|
35
36
|
{{ $t('Add') }}
|
|
36
37
|
</Button>
|
|
37
38
|
</div>
|
|
@@ -59,7 +60,7 @@
|
|
|
59
60
|
</template>
|
|
60
61
|
|
|
61
62
|
<script setup lang="ts">
|
|
62
|
-
import {
|
|
63
|
+
import { IconPlus } from '@iconify-prerendered/vue-lucide';
|
|
63
64
|
import ColumnValueInput from "./ColumnValueInput.vue";
|
|
64
65
|
import { ref, watch, nextTick } from 'vue';
|
|
65
66
|
import { Spinner, Button } from '@/afcl';
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
|
-
<div class="mx-auto grid grid-cols-2 gap-
|
|
3
|
+
<div class="mx-auto grid grid-cols-2 gap-2 mb-2" :class="{hidden: column.type === 'time'}">
|
|
4
4
|
<div class="relative">
|
|
5
5
|
<div class="absolute inset-y-0 end-0 top-0 flex items-center pe-3.5 pointer-events-none">
|
|
6
6
|
<IconCalendar class="w-4 h-4 text-lightDatePickerIcon dark:text-darkDatePickerIcon"/>
|
|
7
7
|
</div>
|
|
8
8
|
|
|
9
9
|
<input ref="datepickerStartEl" type="text"
|
|
10
|
-
class="bg-lightDatePickerButtonBackground border
|
|
10
|
+
class="bg-lightDatePickerButtonBackground border border-lightDatePickerButtonBorder text-lightDatePickerButtonText placeholder-lightDatePickerPlaceHolder text-sm rounded-default shadow-customLight focus:outline-none focus:ring-[3px] focus:ring-lightInputFocusRing focus:border-lightInputFocusBorder block w-full px-2.5 py-1.5 leading-5 dark:bg-darkDatePickerButtonBackground dark:border-darkDatePickerButtonBorder dark:placeholder-darkDatePickerPlaceHolder dark:text-darkDatePickerButtonText dark:focus:ring-darkInputFocusRing dark:focus:border-darkInputFocusBorder"
|
|
11
11
|
:placeholder="$t('From')">
|
|
12
12
|
</div>
|
|
13
13
|
|
|
@@ -17,13 +17,13 @@
|
|
|
17
17
|
</div>
|
|
18
18
|
|
|
19
19
|
<input ref="datepickerEndEl" type="text"
|
|
20
|
-
class="bg-lightDatePickerButtonBackground border
|
|
20
|
+
class="bg-lightDatePickerButtonBackground border border-lightDatePickerButtonBorder text-lightDatePickerButtonText placeholder-lightDatePickerPlaceHolder text-sm rounded-default shadow-customLight focus:outline-none focus:ring-[3px] focus:ring-lightInputFocusRing focus:border-lightInputFocusBorder block w-full px-2.5 py-1.5 leading-5 dark:bg-darkDatePickerButtonBackground dark:border-darkDatePickerButtonBorder dark:placeholder-darkDatePickerPlaceHolder dark:text-darkDatePickerButtonText dark:focus:ring-darkInputFocusRing dark:focus:border-darkInputFocusBorder"
|
|
21
21
|
:placeholder="$t('To')">
|
|
22
22
|
</div>
|
|
23
23
|
</div>
|
|
24
24
|
|
|
25
25
|
<div>
|
|
26
|
-
<div class="mx-auto grid grid-cols-2 gap-
|
|
26
|
+
<div class="mx-auto grid grid-cols-2 gap-2 mb-2" :class="{hidden: !showTimeInputs}">
|
|
27
27
|
<div>
|
|
28
28
|
<div class="relative">
|
|
29
29
|
<div class="absolute inset-y-0 end-0 top-0 flex items-center pe-3.5 pointer-events-none">
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
</div>
|
|
32
32
|
|
|
33
33
|
<input v-model="startTime" type="time" id="start-time"
|
|
34
|
-
class="bg-lightDatePickerButtonBackground border
|
|
34
|
+
class="bg-lightDatePickerButtonBackground border border-lightDatePickerButtonBorder text-lightDatePickerButtonText placeholder-lightDatePickerPlaceHolder text-sm rounded-default shadow-customLight focus:outline-none focus:ring-[3px] focus:ring-lightInputFocusRing focus:border-lightInputFocusBorder block w-full px-2.5 py-1.5 leading-5 dark:bg-darkDatePickerButtonBackground dark:border-darkDatePickerButtonBorder dark:placeholder-darkDatePickerPlaceHolder dark:text-darkDatePickerButtonText dark:focus:ring-darkInputFocusRing dark:focus:border-darkInputFocusBorder"
|
|
35
35
|
value="00:00" required/>
|
|
36
36
|
</div>
|
|
37
37
|
</div>
|
|
@@ -43,17 +43,17 @@
|
|
|
43
43
|
</div>
|
|
44
44
|
|
|
45
45
|
<input v-model="endTime" type="time" id="end-time"
|
|
46
|
-
class="bg-lightDatePickerButtonBackground border
|
|
46
|
+
class="bg-lightDatePickerButtonBackground border border-lightDatePickerButtonBorder text-lightDatePickerButtonText placeholder-lightDatePickerPlaceHolder text-sm rounded-default shadow-customLight focus:outline-none focus:ring-[3px] focus:ring-lightInputFocusRing focus:border-lightInputFocusBorder block w-full px-2.5 py-1.5 leading-5 dark:bg-darkDatePickerButtonBackground dark:border-darkDatePickerButtonBorder dark:placeholder-darkDatePickerPlaceHolder dark:text-darkDatePickerButtonText dark:focus:ring-darkInputFocusRing dark:focus:border-darkInputFocusBorder"
|
|
47
47
|
value="00:00" required/>
|
|
48
48
|
</div>
|
|
49
49
|
</div>
|
|
50
50
|
</div>
|
|
51
51
|
|
|
52
52
|
<button type="button"
|
|
53
|
-
class="text-lightPrimary dark:text-darkPrimary text-
|
|
53
|
+
class="text-lightPrimary dark:text-darkPrimary text-[13px] font-medium hover:underline p-0 inline-flex items-center gap-0.5 mb-2"
|
|
54
54
|
:class="{hidden: column.type !== 'datetime'}"
|
|
55
55
|
@click="toggleTimeInputs">{{ showTimeInputs ? $t('Hide time') : $t('Show time') }}
|
|
56
|
-
<svg class="w-
|
|
56
|
+
<svg class="w-4 h-4" :class="{'rotate-180': showTimeInputs}" aria-hidden="true"
|
|
57
57
|
xmlns="http://www.w3.org/2000/svg" width="24" height="24"
|
|
58
58
|
fill="none" viewBox="0 0 24 24">
|
|
59
59
|
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
:min="minFormatted"
|
|
5
5
|
:max="maxFormatted"
|
|
6
6
|
type="number" aria-describedby="helper-text-explanation"
|
|
7
|
-
class="flex-1 bg-lightRangePickerInputBackground border border-lightRangePickerInputBorder text-lightRangePickerInputText placeholder-lightRangePickerInputPlaceholder text-sm rounded-
|
|
7
|
+
class="flex-1 bg-lightRangePickerInputBackground border border-lightRangePickerInputBorder text-lightRangePickerInputText placeholder-lightRangePickerInputPlaceholder text-sm rounded-default shadow-customLight focus:outline-none focus:ring-[3px] focus:ring-lightInputFocusRing focus:border-lightInputFocusBorder block w-20 px-2.5 py-1.5 leading-5 dark:bg-darkRangePickerInputBackground dark:border-darkRangePickerInputBorder dark:placeholder-darkRangePickerInputPlaceholder dark:text-darkRangePickerInputText dark:focus:ring-darkInputFocusRing dark:focus:border-darkInputFocusBorder"
|
|
8
8
|
:placeholder="$t('From')"
|
|
9
9
|
v-model="start"
|
|
10
10
|
>
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
:min="minFormatted"
|
|
14
14
|
:max="maxFormatted"
|
|
15
15
|
type="number" aria-describedby="helper-text-explanation"
|
|
16
|
-
class="flex-1 bg-lightRangePickerInputBackground border border-lightRangePickerInputBorder text-lightRangePickerInputText placeholder-lightRangePickerInputPlaceholder text-sm rounded-
|
|
16
|
+
class="flex-1 bg-lightRangePickerInputBackground border border-lightRangePickerInputBorder text-lightRangePickerInputText placeholder-lightRangePickerInputPlaceholder text-sm rounded-default shadow-customLight focus:outline-none focus:ring-[3px] focus:ring-lightInputFocusRing focus:border-lightInputFocusBorder block w-20 px-2.5 py-1.5 leading-5 dark:bg-darkRangePickerInputBackground dark:border-darkRangePickerInputBorder dark:placeholder-darkRangePickerInputPlaceholder dark:text-darkRangePickerInputText dark:focus:ring-darkInputFocusRing dark:focus:border-darkInputFocusBorder"
|
|
17
17
|
:placeholder="$t('To')"
|
|
18
18
|
v-model="end"
|
|
19
19
|
>
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div v-if="error" class="af-login-modal-error flex items-center p-
|
|
3
|
-
<
|
|
4
|
-
<path d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z"/>
|
|
5
|
-
</svg>
|
|
2
|
+
<div v-if="error" class="af-login-modal-error flex items-center p-3 mb-4 text-sm rounded-lg border text-lightDanger border-lightDangerBorder bg-lightDangerSoft dark:text-darkDanger dark:border-darkDangerBorder dark:bg-darkDangerSoft" role="alert">
|
|
3
|
+
<IconCircleAlert class="shrink-0 w-4 h-4 me-3" aria-hidden="true" />
|
|
6
4
|
<span class="sr-only">{{ $t('Info') }}</span>
|
|
7
5
|
<div>
|
|
8
6
|
{{ error }}
|
|
@@ -11,6 +9,7 @@
|
|
|
11
9
|
</template>
|
|
12
10
|
|
|
13
11
|
<script setup>
|
|
12
|
+
import { IconCircleAlert } from '@iconify-prerendered/vue-lucide';
|
|
14
13
|
|
|
15
14
|
defineProps({
|
|
16
15
|
error: {
|
|
@@ -2,34 +2,34 @@
|
|
|
2
2
|
<!-- drawer component -->
|
|
3
3
|
<div id="drawer-navigation"
|
|
4
4
|
|
|
5
|
-
class="af-filters-sidebar fixed right-0 z-50 p-
|
|
5
|
+
class="af-filters-sidebar fixed right-0 z-50 p-5 overflow-y-auto transition-transform translate-x-full bg-lightFiltersBackgroung w-[22rem] max-w-full border-l border-lightUserMenuBorder dark:border-darkUserMenuBorder dark:bg-darkFiltersBackgroung shadow-popover dark:shadow-darkPopover"
|
|
6
6
|
|
|
7
7
|
:class="show ? 'top-0 transform-none' : ''"
|
|
8
8
|
tabindex="-1" aria-labelledby="drawer-navigation-label"
|
|
9
9
|
:style="{ height: `calc(100dvh ` }"
|
|
10
10
|
>
|
|
11
|
-
<h5 id="drawer-navigation-label" class="text-base font-semibold text-lightFiltersHeaderText
|
|
11
|
+
<h5 id="drawer-navigation-label" class="text-base font-semibold leading-8 text-lightFiltersHeaderText dark:text-darkFiltersHeaderText">
|
|
12
12
|
{{ $t('Filters') }}
|
|
13
13
|
|
|
14
|
-
<button type="button" @click="$emit('hide')" class="text-lightFiltersCloseIcon bg-transparent hover:bg-lightFiltersCloseIconHoverBackground hover:text-lightFiltersCloseIconHover rounded-
|
|
15
|
-
<
|
|
14
|
+
<button type="button" @click="$emit('hide')" class="text-lightFiltersCloseIcon bg-transparent hover:bg-lightFiltersCloseIconHoverBackground hover:text-lightFiltersCloseIconHover rounded-default text-sm p-1.5 absolute end-4 top-5 inline-flex items-center dark:text-darkFiltersCloseIcon dark:hover:bg-darkFiltersCloseIconHoverBackground dark:hover:text-darkFiltersCloseIconHover" >
|
|
15
|
+
<IconX aria-hidden="true" class="w-4 h-4" />
|
|
16
16
|
<span class="sr-only">{{ $t('Close menu') }}</span>
|
|
17
17
|
</button>
|
|
18
18
|
</h5>
|
|
19
19
|
|
|
20
20
|
<div class="py-4 ">
|
|
21
|
-
<ul class="space-y-
|
|
21
|
+
<ul class="space-y-5 text-sm">
|
|
22
22
|
<li v-for="c in columnsWithFilter" :key="c.name">
|
|
23
23
|
<div class="flex flex-col">
|
|
24
24
|
<div class="flex justify-between items-center">
|
|
25
|
-
<p class="
|
|
25
|
+
<p class="my-1 text-[13px] font-medium text-lightFiltersHeaderText dark:text-darkFiltersHeaderText">{{ c.label }}</p>
|
|
26
26
|
<Tooltip v-if="filtersStore.filters.find(f => f.field === c.name)">
|
|
27
27
|
<button
|
|
28
|
-
class=" flex items-center justify-center w-
|
|
28
|
+
class=" flex items-center justify-center w-6 h-6 my-0.5 rounded-default text-lightFiltersCloseIcon hover:text-lightFiltersCloseIconHover hover:bg-lightFiltersCloseIconHoverBackground dark:text-darkFiltersCloseIcon dark:hover:text-darkFiltersCloseIconHover dark:hover:bg-darkFiltersCloseIconHoverBackground"
|
|
29
29
|
:disabled="!filtersStore.filters.find(f => f.field === c.name)"
|
|
30
30
|
@click="filtersStore.clearFilter(c.name);"
|
|
31
31
|
>
|
|
32
|
-
<
|
|
32
|
+
<IconX class="w-3.5 h-3.5" />
|
|
33
33
|
</button>
|
|
34
34
|
<template #tooltip>
|
|
35
35
|
Clear filter
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
:modelValue="filtersStore.filters.find(f => f.field === c.name && f.operator === (c.filterOptions?.multiselect ? AFFO.IN : AFFO.EQ))?.value || (c.filterOptions?.multiselect ? [] : '')"
|
|
70
70
|
>
|
|
71
71
|
<template #extra-item v-if="columnLoadingState[c.name]?.loading">
|
|
72
|
-
<div class="text-center text-
|
|
72
|
+
<div class="text-center text-lightDropdownButtonsPlaceholderText dark:text-darkDropdownButtonsPlaceholderText py-2 flex items-center justify-center gap-2">
|
|
73
73
|
<Spinner class="w-4 h-4" />
|
|
74
74
|
{{ $t('Loading...') }}
|
|
75
75
|
</div>
|
|
@@ -153,13 +153,13 @@
|
|
|
153
153
|
<button
|
|
154
154
|
:disabled="!filtersStore.visibleFiltersCount"
|
|
155
155
|
type="button"
|
|
156
|
-
class="flex gap-1 items-center
|
|
157
|
-
@click="clear"><
|
|
156
|
+
class="flex gap-1.5 items-center h-[2.125rem] px-3 text-sm font-medium text-lightFiltersClearAllButtonText shadow-customLight focus:outline-none bg-lightFiltersClearAllButtonBackground rounded-default border border-lightFiltersClearAllButtonBorder hover:bg-lightFiltersClearAllButtonBackgroundHover hover:text-lightFiltersClearAllButtonTextHover focus-visible:z-10 focus-visible:ring-[3px] focus-visible:ring-lightFiltersClearAllButtonFocus dark:focus-visible:ring-darkFiltersClearAllButtonFocus dark:bg-darkFiltersClearAllButtonBackground dark:text-darkFiltersClearAllButtonText dark:border-darkFiltersClearAllButtonBorder dark:hover:text-darkFiltersClearAllButtonTextHover dark:hover:bg-darkFiltersClearAllButtonBackgroundHover disabled:opacity-50 disabled:cursor-not-allowed"
|
|
157
|
+
@click="clear"><IconX class="w-4 h-4"/> {{ $t('Clear all') }}</button>
|
|
158
158
|
|
|
159
159
|
</div>
|
|
160
160
|
</div>
|
|
161
161
|
|
|
162
|
-
<div v-if="show" class="bg-
|
|
162
|
+
<div v-if="show" class="bg-zinc-900/30 dark:bg-black/60 fixed inset-0 z-40"
|
|
163
163
|
@click="$emit('hide')">
|
|
164
164
|
</div>
|
|
165
165
|
</template>
|
|
@@ -177,7 +177,7 @@ import Select from '@/afcl/Select.vue';
|
|
|
177
177
|
import Spinner from '@/afcl/Spinner.vue';
|
|
178
178
|
import debounce from 'debounce';
|
|
179
179
|
import { Tooltip } from '@/afcl';
|
|
180
|
-
import {
|
|
180
|
+
import { IconX } from '@iconify-prerendered/vue-lucide';
|
|
181
181
|
import type { AdminforthFilterStore, AdminforthFilterStoreUnwrapped } from '@/spa_types/core';
|
|
182
182
|
import type { AdminForthResourceColumnCommon, FilterParams, ColumnMinMaxValue } from '@/types/Common';
|
|
183
183
|
import { AdminForthFilterOperators } from '@/types/Common';
|