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.
Files changed (94) hide show
  1. package/dist/modules/codeInjector.d.ts.map +1 -1
  2. package/dist/modules/codeInjector.js +20 -3
  3. package/dist/modules/codeInjector.js.map +1 -1
  4. package/dist/modules/styleGenerator.d.ts +13 -0
  5. package/dist/modules/styleGenerator.d.ts.map +1 -1
  6. package/dist/modules/styleGenerator.js +274 -1
  7. package/dist/modules/styleGenerator.js.map +1 -1
  8. package/dist/modules/styles.d.ts +24 -0
  9. package/dist/modules/styles.d.ts.map +1 -1
  10. package/dist/modules/styles.js +452 -427
  11. package/dist/modules/styles.js.map +1 -1
  12. package/dist/modules/utils.d.ts +1 -13
  13. package/dist/modules/utils.d.ts.map +1 -1
  14. package/dist/modules/utils.js +2 -275
  15. package/dist/modules/utils.js.map +1 -1
  16. package/dist/spa/index.html +2 -2
  17. package/dist/spa/package-lock.json +1373 -1136
  18. package/dist/spa/package.json +18 -15
  19. package/dist/spa/pnpm-lock.yaml +1067 -648
  20. package/dist/spa/src/App.vue +84 -92
  21. package/dist/spa/src/afcl/AreaChart.vue +8 -24
  22. package/dist/spa/src/afcl/BarChart.vue +8 -23
  23. package/dist/spa/src/afcl/Button.vue +8 -2
  24. package/dist/spa/src/afcl/ButtonGroup.vue +9 -9
  25. package/dist/spa/src/afcl/Card.vue +40 -19
  26. package/dist/spa/src/afcl/Checkbox.vue +6 -6
  27. package/dist/spa/src/afcl/CountryFlag.vue +17 -11
  28. package/dist/spa/src/afcl/DatePicker.vue +7 -7
  29. package/dist/spa/src/afcl/Dialog.vue +8 -9
  30. package/dist/spa/src/afcl/DropdownMenu.vue +210 -0
  31. package/dist/spa/src/afcl/DropdownMenuAccordion.vue +56 -0
  32. package/dist/spa/src/afcl/DropdownMenuItem.vue +86 -0
  33. package/dist/spa/src/afcl/Dropzone.vue +10 -26
  34. package/dist/spa/src/afcl/Input.vue +4 -4
  35. package/dist/spa/src/afcl/Link.vue +1 -1
  36. package/dist/spa/src/afcl/LinkButton.vue +15 -1
  37. package/dist/spa/src/afcl/MixedChart.vue +4 -18
  38. package/dist/spa/src/afcl/Modal.vue +9 -9
  39. package/dist/spa/src/afcl/PieChart.vue +8 -29
  40. package/dist/spa/src/afcl/ProgressBar.vue +2 -2
  41. package/dist/spa/src/afcl/Select.vue +20 -20
  42. package/dist/spa/src/afcl/Skeleton.vue +1 -1
  43. package/dist/spa/src/afcl/Spinner.vue +1 -1
  44. package/dist/spa/src/afcl/Table.vue +19 -26
  45. package/dist/spa/src/afcl/Textarea.vue +1 -1
  46. package/dist/spa/src/afcl/Toggle.vue +4 -4
  47. package/dist/spa/src/afcl/Tooltip.vue +1 -1
  48. package/dist/spa/src/afcl/TreeMapChart.vue +5 -20
  49. package/dist/spa/src/afcl/VerticalTabs.vue +4 -4
  50. package/dist/spa/src/afcl/buttonStyles.ts +73 -33
  51. package/dist/spa/src/afcl/chartUtils.ts +19 -0
  52. package/dist/spa/src/afcl/classMerge.ts +11 -0
  53. package/dist/spa/src/afcl/dropdownMenuContext.ts +10 -0
  54. package/dist/spa/src/afcl/fileSize.ts +12 -0
  55. package/dist/spa/src/afcl/index.ts +3 -0
  56. package/dist/spa/src/components/AcceptModal.vue +17 -19
  57. package/dist/spa/src/components/Breadcrumbs.vue +11 -13
  58. package/dist/spa/src/components/BreadcrumbsWithButtons.vue +2 -2
  59. package/dist/spa/src/components/CallActionWrapper.vue +3 -0
  60. package/dist/spa/src/components/ColumnValueInput.vue +5 -5
  61. package/dist/spa/src/components/ColumnValueInputWrapper.vue +7 -6
  62. package/dist/spa/src/components/CustomDateRangePicker.vue +8 -8
  63. package/dist/spa/src/components/CustomRangePicker.vue +2 -2
  64. package/dist/spa/src/components/ErrorMessage.vue +3 -4
  65. package/dist/spa/src/components/Filters.vue +13 -13
  66. package/dist/spa/src/components/GroupsTable.vue +12 -12
  67. package/dist/spa/src/components/ListActionsThreeDots.vue +89 -207
  68. package/dist/spa/src/components/MenuLink.vue +23 -20
  69. package/dist/spa/src/components/RangePicker.vue +9 -10
  70. package/dist/spa/src/components/ResourceListTable.vue +68 -65
  71. package/dist/spa/src/components/ShowTable.vue +8 -8
  72. package/dist/spa/src/components/Sidebar.vue +31 -38
  73. package/dist/spa/src/components/ThreeDotsMenu.vue +88 -136
  74. package/dist/spa/src/components/Toast.vue +16 -23
  75. package/dist/spa/src/components/UserMenuSettingsButton.vue +15 -36
  76. package/dist/spa/src/components/ValueRenderer.vue +13 -8
  77. package/dist/spa/src/components/icons/IconCalendar.vue +3 -3
  78. package/dist/spa/src/components/icons/IconTime.vue +3 -3
  79. package/dist/spa/src/index.scss +6 -2
  80. package/dist/spa/src/main.ts +2 -0
  81. package/dist/spa/src/renderers/CompactField.vue +3 -3
  82. package/dist/spa/src/renderers/CompactUUID.vue +3 -3
  83. package/dist/spa/src/renderers/SensitiveBlurCell.vue +9 -9
  84. package/dist/spa/src/utils/threeDotsMenu.ts +7 -0
  85. package/dist/spa/src/utils/userMenu.ts +5 -0
  86. package/dist/spa/src/utils/utils.ts +12 -39
  87. package/dist/spa/src/views/CreateEditSkeleton.vue +3 -3
  88. package/dist/spa/src/views/CreateView.vue +5 -6
  89. package/dist/spa/src/views/EditView.vue +5 -6
  90. package/dist/spa/src/views/ListView.vue +114 -115
  91. package/dist/spa/src/views/LoginView.vue +4 -4
  92. package/dist/spa/src/views/ShowView.vue +17 -18
  93. package/dist/spa/vite.config.ts +23 -16
  94. package/package.json +1 -2
@@ -1,70 +1,110 @@
1
- import { extendTailwindMerge, type ClassNameValue } 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
- 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 ButtonVariant = 'primary' | 'secondary' | 'danger';
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-4 focus:outline-none
18
- focus:ring-opacity-50 font-medium rounded-default
19
- text-sm px-5 py-2.5 text-center transition-all duration-200
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
- export const buttonVariantStyles: Record<ButtonVariant, string> = {
15
+ const variantStyles: Record<ButtonVariant, string> = {
23
16
  primary: `
24
17
  text-lightButtonsText bg-lightButtonsBackground border-lightButtonsBorder
25
- dark:bg-darkButtonsBackground hover:bg-lightButtonsHover
26
- hover:border-lightButtonsBorderHover focus:ring-lightButtonFocusRing
27
- dark:focus:ring-darkButtonFocusRing dark:text-darkButtonsText
28
- dark:border-darkButtonsBorder dark:hover:bg-darkButtonsHover
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/15
34
- hover:bg-lightSecondaryDarken focus:ring-lightSecondary hover:text-lightPrimary
25
+ text-lightSecondaryContrast/90 bg-lightSecondary border-lightSecondaryContrast/[0.17]
26
+ focus-visible:ring-lightFocusRing
35
27
 
36
- dark:bg-darkSecondary dark:focus:ring-darkSecondary/40 dark:text-darkSecondaryContrast/60
37
- dark:border-darkSecondaryContrast/15 dark:hover:bg-darkSecondaryLighten
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
- hover:bg-lightAcceptModalConfirmButtonBackgroundHover dark:hover:bg-darkAcceptModalConfirmButtonBackgroundHover
45
- focus:ring-lightAcceptModalConfirmButtonFocus dark:focus:ring-darkAcceptModalConfirmButtonFocus
46
- border-transparent hover:border-transparent
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-default opacity-50 pointer-events-none';
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
- return twMerge(
98
+ const variant = options.variant ?? 'primary';
99
+ const size = options.size ?? 'md';
100
+ return mergeClasses(
65
101
  buttonBaseStyles,
66
- buttonVariantStyles[options.variant ?? 'primary'],
67
- options.shadow && 'af-button-shadow',
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:p-8 sm:w-[440px] rounded-lg shadow-xl bg-lightAcceptModalBackground dark:bg-darkAcceptModalBackground" >
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-4 right-4 text-gray-400 hover:text-gray-900 transition-colors dark:hover:text-white" >
12
- <svg class="w-3.5 h-3.5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
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-16 w-16 rounded-full mb-4 relative"
19
- :class="modalStore.modalContent.dangerous ? 'bg-red-50 dark:bg-red-900/20' : 'bg-lightPrimaryOpacity dark:bg-darkPrimaryOpacity'">
20
- <IconClipboardDocumentSolid class="w-10 h-10"
21
- :class="modalStore.modalContent.dangerous ? 'text-red-500' : 'text-lightButtonsBackground dark:text-darkButtonsBackground'" />
22
- <div class="absolute bottom-1 right-1 rounded-default w-[18px] h-[18px] flex items-center justify-center border-2 border-white dark:border-gray-800"
23
- :class="modalStore.modalContent.dangerous ? 'bg-red-500' : 'bg-lightButtonsBackground dark:bg-darkButtonsBackground'">
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-2xl font-bold text-gray-900 dark:text-white">
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-[15px] text-gray-600 dark:text-gray-300">
34
- <div v-if="modalStore?.modalContent?.contentHTML" class="font-medium" v-html="modalStore.modalContent.contentHTML"></div>
35
- <p v-else-if="modalStore?.modalContent?.content" class="font-medium">{{ modalStore.modalContent.content }}</p>
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-2 border-gray-300 dark:border-gray-500 my-6">
37
+ <hr class="border-t border-lightDialogBreakLine dark:border-darkDialogBreakLine my-5">
40
38
 
41
- <div class="flex justify-center gap-4 w-full">
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-6 text-xs text-gray-400 gap-1.5 font-medium">
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 { IconClipboardDocumentSolid, IconShieldCheck } from '@iconify-prerendered/vue-heroicons';
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 font-medium text-lightBreadcrumbsHomepageText hover:text-lightBreadcrumbsHomepageTextHover dark:text-darkBreadcrumbsHomepageText dark:hover:text-darkBreadcrumbsHomepageTextHover">
6
- <svg class="w-3 h-3 me-2.5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20">
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
- <svg class="rtl:rotate-180 w-3 h-3 text-lightBreadcrumbsArrowIcon dark:text-darkBreadcrumbsArrowIcon mx-1" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10">
15
- <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 9 4-4-4-4"/>
16
- </svg>
17
- <RouterLink :to="{name: 'resource-list', params: { resourceId: $route.params.resourceId }}" class="text-sm font-medium text-lightBreadcrumbsText md:ms-2 dark:text-darkBreadcrumbsText">{{ coreStore.resourceById[$route.params.resourceId]?.label }}</RouterLink>
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
- <svg class="rtl:rotate-180 w-3 h-3 text-lightBreadcrumbsArrowIcon dark:text-darkBreadcrumbsArrowIcon mx-1" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10">
24
- <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 9 4-4-4-4"/>
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 flex-wrap gap-y-2 gap-2">
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 space-x-1 flex-wrap gap-y-1">
5
+ <div class="flex items-center gap-2 flex-wrap gap-y-1">
6
6
  <slot></slot>
7
7
  </div>
8
8
  </div>
@@ -12,4 +12,7 @@ function onClick() {
12
12
  if (props.disabled) return;
13
13
  emit('callAction', props.extra);
14
14
  }
15
+
16
+ // menus forward clicks on the item padding around the wrapper here
17
+ defineExpose({ click: onClick });
15
18
  </script>
@@ -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-gray-400 dark:text-gray-300 py-2 flex items-center justify-center gap-2">
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
- <IconTrashBinSolid class="w-6 h-6 text-lightInputIcons dark:text-darkInputIcons"/>
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
- <IconEyeSolid class="w-6 h-6 text-lightInputIcons dark:text-darkInputIcons" v-if="!unmasked[column.name]"/>
169
- <IconEyeSlashSolid class="w-6 h-6 text-lightInputIcons dark:text-darkInputIcons" v-else />
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 { IconEyeSlashSolid, IconEyeSolid, IconTrashBinSolid } from '@iconify-prerendered/vue-flowbite';
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
- @click="addArrayItem"
31
- class="flex items-center py-1 px-3 me-2 text-sm font-medium rounded-default text-lightInputText focus:outline-none bg-lightInputBackground rounded border border-lightInputBorder hover:bg-lightInputBackgroundHover hover:text-lightInputTextHover hover:border-lightInputBorderHover focus:z-10 focus:ring-4 focus:ring-lightInputFocusRing dark:focus:ring-darkInputFocusRing dark:bg-darkInputBackground dark:text-darkInputText dark:border-darkInputBorder dark:hover:darkInputTextHover dark:hover:bg-darkInputHover"
32
- :class="{'mt-2': currentValues[column.name].length}"
33
- >
34
- <IconPlusOutline class="w-4 h-4"/>
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 { IconPlusOutline } from '@iconify-prerendered/vue-flowbite';
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-4 mb-2" :class="{hidden: column.type === 'time'}">
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 leading-none border-lightDatePickerButtonBorder text-lightDatePickerButtonText placeholder-lightDatePickerPlaceHolder text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-darkDatePickerButtonBackground dark:border-darkDatePickerButtonBorder dark:placeholder-darkDatePickerPlaceHolder dark:text-darkDatePickerButtonText dark:focus:ring-blue-500 dark:focus:border-blue-500"
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 leading-none border-lightDatePickerButtonBorder text-lightDatePickerButtonText placeholder-lightDatePickerPlaceHolder text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-darkDatePickerButtonBackground dark:border-darkDatePickerButtonBorder dark:placeholder-darkDatePickerPlaceHolder dark:text-darkDatePickerButtonText dark:focus:ring-blue-500 dark:focus:border-blue-500"
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-4 mb-2" :class="{hidden: !showTimeInputs}">
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 leading-none border-lightDatePickerButtonBorder text-lightDatePickerButtonText placeholder-lightDatePickerPlaceHolder text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-darkDatePickerButtonBackground dark:border-darkDatePickerButtonBorder dark:placeholder-darkDatePickerPlaceHolder dark:text-darkDatePickerButtonText dark:focus:ring-blue-500 dark:focus:border-blue-500"
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 leading-none border-lightDatePickerButtonBorder text-lightDatePickerButtonText placeholder-lightDatePickerPlaceHolder text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-darkDatePickerButtonBackground dark:border-darkDatePickerButtonBorder dark:placeholder-darkDatePickerPlaceHolder dark:text-darkDatePickerButtonText dark:focus:ring-blue-500 dark:focus:border-blue-500"
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-base font-medium hover:underline p-0 inline-flex items-center mb-2"
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-8 h-8 ms-0.5 relative top-px" :class="{'rotate-180': showTimeInputs}" aria-hidden="true"
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-lg focus:ring-blue-500 focus:border-blue-500 block w-20 p-2.5 dark:bg-darkRangePickerInputBackground dark:border-darkRangePickerInputBorder dark:placeholder-darkRangePickerInputPlaceholder dark:text-darkRangePickerInputText dark:focus:ring-blue-500 dark:focus:border-blue-500"
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-lg focus:ring-blue-500 focus:border-blue-500 block w-20 p-2.5 dark:bg-darkRangePickerInputBackground dark:border-darkRangePickerInputBorder dark:placeholder-darkRangePickerInputPlaceholder dark:text-darkRangePickerInputText dark:focus:ring-blue-500 dark:focus:border-blue-500"
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-4 mb-4 text-sm text-red-800 rounded-lg bg-red-50 dark:bg-gray-800 dark:text-red-400" role="alert">
3
- <svg class="flex-shrink-0 inline w-4 h-4 me-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20">
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-4 overflow-y-auto transition-transform translate-x-full bg-lightFiltersBackgroung w-80 dark:bg-darkFiltersBackgroung shadow-xl dark:shadow-gray-900"
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 uppercase dark:text-darkFiltersHeaderText">
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-lg text-sm p-1.5 absolute end-2.5 inline-flex items-center dark:text-darkFiltersCloseIcon dark:hover:bg-darkFiltersCloseIconHoverBackground dark:hover:text-darkFiltersCloseIconHover" >
15
- <svg aria-hidden="true" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg>
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-3 font-medium text-sm">
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="dark:text-gray-400 my-1">{{ c.label }}</p>
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-7 h-7 my-1 hover:border rounded-md hover:bg-gray-100 dark:hover:bg-gray-700"
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
- <IconCloseOutline />
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-gray-400 dark:text-gray-300 py-2 flex items-center justify-center gap-2">
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 py-1 pr-3 text-sm font-medium text-lightFiltersClearAllButtonText focus:outline-none bg-lightFiltersClearAllButtonBackground rounded-default border border-lightFiltersClearAllButtonBorder hover:bg-lightFiltersClearAllButtonBackgroundHover hover:text-lightFiltersClearAllButtonTextHover focus:z-10 focus:ring-4 focus:ring-lightFiltersClearAllButtonFocus dark:focus: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"><IconCloseOutline class="ml-3"/> {{ $t('Clear all') }}</button>
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-gray-900/50 dark:bg-gray-900/80 fixed inset-0 z-40"
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 { IconCloseOutline } from '@iconify-prerendered/vue-flowbite';
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';