adminforth 2.4.0-next.12 → 2.4.0-next.121

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 (145) hide show
  1. package/commands/callTsProxy.js +14 -4
  2. package/commands/cli.js +12 -4
  3. package/commands/createApp/templates/custom/tsconfig.json.hbs +2 -3
  4. package/commands/createApp/templates/index.ts.hbs +8 -1
  5. package/commands/createApp/templates/package.json.hbs +1 -1
  6. package/commands/createApp/utils.js +27 -2
  7. package/commands/createCustomComponent/configLoader.js +3 -0
  8. package/dist/dataConnectors/baseConnector.d.ts.map +1 -1
  9. package/dist/dataConnectors/baseConnector.js +16 -3
  10. package/dist/dataConnectors/baseConnector.js.map +1 -1
  11. package/dist/dataConnectors/clickhouse.d.ts.map +1 -1
  12. package/dist/dataConnectors/clickhouse.js +4 -0
  13. package/dist/dataConnectors/clickhouse.js.map +1 -1
  14. package/dist/dataConnectors/mongo.d.ts.map +1 -1
  15. package/dist/dataConnectors/mongo.js +14 -14
  16. package/dist/dataConnectors/mongo.js.map +1 -1
  17. package/dist/index.d.ts +2 -1
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +20 -9
  20. package/dist/index.js.map +1 -1
  21. package/dist/modules/codeInjector.d.ts.map +1 -1
  22. package/dist/modules/codeInjector.js +22 -5
  23. package/dist/modules/codeInjector.js.map +1 -1
  24. package/dist/modules/configValidator.d.ts.map +1 -1
  25. package/dist/modules/configValidator.js +48 -1
  26. package/dist/modules/configValidator.js.map +1 -1
  27. package/dist/modules/restApi.d.ts.map +1 -1
  28. package/dist/modules/restApi.js +145 -25
  29. package/dist/modules/restApi.js.map +1 -1
  30. package/dist/modules/styles.d.ts +451 -13
  31. package/dist/modules/styles.d.ts.map +1 -1
  32. package/dist/modules/styles.js +507 -31
  33. package/dist/modules/styles.js.map +1 -1
  34. package/dist/modules/utils.d.ts +1 -0
  35. package/dist/modules/utils.d.ts.map +1 -1
  36. package/dist/modules/utils.js +9 -0
  37. package/dist/modules/utils.js.map +1 -1
  38. package/dist/spa/index.html +1 -1
  39. package/dist/spa/src/App.vue +25 -15
  40. package/dist/spa/src/adminforth.ts +10 -0
  41. package/dist/spa/src/afcl/Button.vue +6 -6
  42. package/dist/spa/src/afcl/Checkbox.vue +21 -13
  43. package/dist/spa/src/afcl/CountryFlag.vue +4 -1
  44. package/dist/spa/src/{components/CustomDatePicker.vue → afcl/DatePicker.vue} +95 -9
  45. package/dist/spa/src/afcl/Dialog.vue +43 -26
  46. package/dist/spa/src/afcl/Dropzone.vue +10 -10
  47. package/dist/spa/src/afcl/Input.vue +9 -7
  48. package/dist/spa/src/afcl/JsonViewer.vue +25 -0
  49. package/dist/spa/src/afcl/Link.vue +1 -1
  50. package/dist/spa/src/afcl/LinkButton.vue +1 -1
  51. package/dist/spa/src/afcl/ProgressBar.vue +7 -7
  52. package/dist/spa/src/afcl/Select.vue +60 -27
  53. package/dist/spa/src/afcl/Skeleton.vue +6 -6
  54. package/dist/spa/src/afcl/Table.vue +13 -13
  55. package/dist/spa/src/afcl/Textarea.vue +31 -0
  56. package/dist/spa/src/afcl/Toggle.vue +32 -0
  57. package/dist/spa/src/afcl/Tooltip.vue +2 -3
  58. package/dist/spa/src/afcl/VerticalTabs.vue +3 -3
  59. package/dist/spa/src/afcl/index.ts +4 -3
  60. package/dist/spa/src/components/AcceptModal.vue +7 -7
  61. package/dist/spa/src/components/Breadcrumbs.vue +5 -5
  62. package/dist/spa/src/components/ColumnValueInput.vue +37 -18
  63. package/dist/spa/src/components/ColumnValueInputWrapper.vue +4 -3
  64. package/dist/spa/src/components/CustomDateRangePicker.vue +9 -8
  65. package/dist/spa/src/components/CustomRangePicker.vue +37 -8
  66. package/dist/spa/src/components/Filters.vue +83 -37
  67. package/dist/spa/src/components/GroupsTable.vue +9 -8
  68. package/dist/spa/src/components/MenuLink.vue +3 -3
  69. package/dist/spa/src/components/ResourceForm.vue +94 -51
  70. package/dist/spa/src/components/ResourceListTable.vue +38 -40
  71. package/dist/spa/src/components/ResourceListTableVirtual.vue +31 -33
  72. package/dist/spa/src/components/ShowTable.vue +17 -12
  73. package/dist/spa/src/components/SingleSkeletLoader.vue +6 -6
  74. package/dist/spa/src/components/SkeleteLoader.vue +1 -1
  75. package/dist/spa/src/components/ThreeDotsMenu.vue +49 -7
  76. package/dist/spa/src/components/Toast.vue +2 -7
  77. package/dist/spa/src/components/ValueRenderer.vue +4 -4
  78. package/dist/spa/src/controls/BoolToggle.vue +34 -0
  79. package/dist/spa/src/i18n.ts +1 -1
  80. package/dist/spa/src/shims-vue.d.ts +5 -0
  81. package/dist/spa/src/spa_types/core.ts +7 -0
  82. package/dist/spa/src/stores/core.ts +1 -1
  83. package/dist/spa/src/types/Back.ts +82 -21
  84. package/dist/spa/src/types/Common.ts +25 -10
  85. package/dist/spa/src/types/FrontendAPI.ts +8 -0
  86. package/dist/spa/src/types/adapters/CompletionAdapter.ts +25 -0
  87. package/dist/spa/src/types/adapters/EmailAdapter.ts +27 -0
  88. package/dist/spa/src/types/adapters/ImageGenerationAdapter.ts +50 -0
  89. package/dist/spa/src/types/adapters/ImageVisionAdapter.ts +30 -0
  90. package/dist/spa/src/types/adapters/OAuth2Adapter.ts +34 -0
  91. package/dist/spa/src/types/adapters/StorageAdapter.ts +73 -0
  92. package/dist/spa/src/types/adapters/index.ts +6 -0
  93. package/dist/spa/src/utils.ts +217 -7
  94. package/dist/spa/src/views/CreateView.vue +21 -18
  95. package/dist/spa/src/views/EditView.vue +29 -19
  96. package/dist/spa/src/views/ListView.vue +60 -51
  97. package/dist/spa/src/views/LoginView.vue +50 -47
  98. package/dist/spa/src/views/ResourceParent.vue +1 -1
  99. package/dist/spa/src/views/ShowView.vue +34 -13
  100. package/dist/spa/src/websocket.ts +6 -1
  101. package/dist/spa/tsconfig.app.json +1 -1
  102. package/dist/spa/vite.config.ts +44 -1
  103. package/dist/types/Back.d.ts +61 -14
  104. package/dist/types/Back.d.ts.map +1 -1
  105. package/dist/types/Back.js.map +1 -1
  106. package/dist/types/Common.d.ts +23 -8
  107. package/dist/types/Common.d.ts.map +1 -1
  108. package/dist/types/Common.js.map +1 -1
  109. package/dist/types/FrontendAPI.d.ts +7 -0
  110. package/dist/types/FrontendAPI.d.ts.map +1 -1
  111. package/dist/types/FrontendAPI.js.map +1 -1
  112. package/dist/types/adapters/CompletionAdapter.d.ts +20 -0
  113. package/dist/types/adapters/CompletionAdapter.d.ts.map +1 -0
  114. package/dist/types/adapters/CompletionAdapter.js +2 -0
  115. package/dist/types/adapters/CompletionAdapter.js.map +1 -0
  116. package/dist/types/adapters/EmailAdapter.d.ts +20 -0
  117. package/dist/types/adapters/EmailAdapter.d.ts.map +1 -0
  118. package/dist/types/adapters/EmailAdapter.js +2 -0
  119. package/dist/types/adapters/EmailAdapter.js.map +1 -0
  120. package/dist/types/adapters/ImageGenerationAdapter.d.ts +37 -0
  121. package/dist/types/adapters/ImageGenerationAdapter.d.ts.map +1 -0
  122. package/dist/types/adapters/ImageGenerationAdapter.js +2 -0
  123. package/dist/types/adapters/ImageGenerationAdapter.js.map +1 -0
  124. package/dist/types/adapters/ImageVisionAdapter.d.ts +25 -0
  125. package/dist/types/adapters/ImageVisionAdapter.d.ts.map +1 -0
  126. package/dist/types/adapters/ImageVisionAdapter.js +2 -0
  127. package/dist/types/adapters/ImageVisionAdapter.js.map +1 -0
  128. package/dist/types/adapters/OAuth2Adapter.d.ts +32 -0
  129. package/dist/types/adapters/OAuth2Adapter.d.ts.map +1 -0
  130. package/dist/types/adapters/OAuth2Adapter.js +2 -0
  131. package/dist/types/adapters/OAuth2Adapter.js.map +1 -0
  132. package/dist/types/adapters/StorageAdapter.d.ts +63 -0
  133. package/dist/types/adapters/StorageAdapter.d.ts.map +1 -0
  134. package/dist/types/adapters/StorageAdapter.js +2 -0
  135. package/dist/types/adapters/StorageAdapter.js.map +1 -0
  136. package/dist/types/adapters/index.d.ts +7 -0
  137. package/dist/types/adapters/index.d.ts.map +1 -0
  138. package/dist/types/adapters/index.js +2 -0
  139. package/dist/types/adapters/index.js.map +1 -0
  140. package/package.json +2 -2
  141. package/dist/spa/src/types/Adapters.ts +0 -213
  142. package/dist/types/Adapters.d.ts +0 -168
  143. package/dist/types/Adapters.d.ts.map +0 -1
  144. package/dist/types/Adapters.js +0 -2
  145. package/dist/types/Adapters.js.map +0 -1
@@ -1,9 +1,9 @@
1
1
  <template>
2
2
 
3
- <div class="flex z-0" :class="{'opacity-50' : readonly}">
3
+ <div class="afcl-input-wrapper flex z-0 relative" :class="{'opacity-50' : readonly}">
4
4
  <span
5
5
  v-if="$slots.prefix || prefix"
6
- class="inline-flex items-center px-3 text-sm text-gray-900 bg-gray-200 border border-s-0 border-gray-300 rounded-s-md dark:bg-gray-600 dark:text-gray-400 dark:border-gray-600">
6
+ class="inline-flex items-center px-3 text-sm text-lightInputText bg-lightInputBackground border border-s-0 border-lightInputBorder rounded-s-md dark:bg-darkInputBackground dark:text-darkInputText dark:border-darkInputBorder">
7
7
  <slot name="prefix">{{ prefix }}</slot>
8
8
  </span>
9
9
 
@@ -12,19 +12,21 @@
12
12
  ref="input"
13
13
  v-bind="$attrs"
14
14
  :type="type"
15
- @input="$emit('update:modelValue', $event.target?.value)"
15
+ @input="$emit('update:modelValue', type === 'number' ? Number($event.target?.value) : $event.target?.value)"
16
16
  :value="modelValue"
17
17
  aria-describedby="helper-text-explanation"
18
- class="inline-flex bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-0 focus:ring-lightPrimary focus:border-lightPrimary dark:focus:ring-darkPrimary dark:focus:border-darkPrimary
19
- blue-500 focus:border-blue-500 block w-20 p-2.5 dark:bg-gray-700 dark:border-gray-600 placeholder-gray-500 dark:placeholder-gray-400 dark:text-white translate-y-0"
18
+ class="afcl-input inline-flex bg-lightInputBackground border border-lightInputBorder text-lightInputText text-sm rounded-0 focus:ring-lightPrimary focus:border-lightPrimary dark:focus:ring-darkPrimary dark:focus:border-darkPrimary
19
+ blue-500 focus:border-blue-500 block w-20 p-2.5 dark:bg-darkInputBackground dark:border-darkInputBorder placeholder-lightInputPlaceholderText dark:placeholder-darkInputPlaceholderText dark:text-darkInputText translate-y-0"
20
20
  :class="{'rounded-l-md': !$slots.prefix && !prefix, 'rounded-r-md': !$slots.suffix && !suffix, 'w-full': fullWidth}"
21
21
  :disabled="readonly"
22
22
  >
23
23
 
24
-
24
+ <div v-if="$slots.rightIcon" class="absolute inset-y-0 right-0 pr-3 flex items-center">
25
+ <slot name="rightIcon" />
26
+ </div>
25
27
  <span
26
28
  v-if="$slots.suffix || suffix"
27
- class="inline-flex items-center px-3 text-sm text-gray-900 bg-gray-200 border border-s-0 border-gray-300 rounded-e-md dark:bg-gray-600 dark:text-gray-400 dark:border-gray-600 ">
29
+ class="inline-flex items-center px-3 text-sm text-lightInputText bg-lightInputBackground border border-s-0 border-lightInputBorder rounded-e-md dark:bg-darkInputBackground dark:text-darkInputText dark:border-darkInputBorder ">
28
30
  <slot name="suffix">{{ suffix }}</slot>
29
31
  </span>
30
32
 
@@ -0,0 +1,25 @@
1
+ <template>
2
+ <JsonViewer
3
+ class="afcl-json-viewer min-w-[6rem]"
4
+ :value="value"
5
+ :expandDepth="expandDepth"
6
+ copyable
7
+ sort
8
+ :theme="currentTheme"
9
+ />
10
+ </template>
11
+
12
+ <script setup lang="ts">
13
+ import { computed } from 'vue'
14
+ import { JsonViewer } from 'vue3-json-viewer'
15
+ import { useCoreStore } from '@/stores/core'
16
+
17
+ defineProps<{
18
+ value: any
19
+ expandDepth?: number
20
+ }>()
21
+
22
+ const coreStore = useCoreStore()
23
+
24
+ const currentTheme = computed(() => (coreStore.theme === 'dark' ? 'dark' : 'light'))
25
+ </script>
@@ -2,7 +2,7 @@
2
2
  <router-link
3
3
  v-bind="$attrs"
4
4
  :to="to"
5
- class="text-lightPrimary underline dark:text-darkPrimary hover:no-underline hover:brightness-110
5
+ class="afcl-link text-lightPrimary underline dark:text-darkPrimary hover:no-underline hover:brightness-110
6
6
  cursor-pointer"
7
7
  >
8
8
  <slot></slot>
@@ -3,7 +3,7 @@
3
3
  v-bind="$attrs"
4
4
  :to="props.to"
5
5
  type="submit"
6
- class="flex items-center justify-center gap-1 text-lightPrimaryContrast bg-lightPrimary dark:bg-darkPrimary hover:brightness-110
6
+ class="afcl-link-button flex items-center justify-center gap-1 text-lightPrimaryContrast bg-lightPrimary dark:bg-darkPrimary hover:brightness-110
7
7
  focus:ring-4 focus:outline-none focus:ring-lightPrimary focus:ring-opacity-50 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:focus:ring-darkPrimary dark:focus:ring-opacity-50"
8
8
  :class="{
9
9
  'cursor-default': props.disabled,
@@ -1,14 +1,14 @@
1
1
  <template>
2
- <div class="relative mt-4 lg:mt-10 w-full max-w-[700px] bg-gray-200 rounded-full h-2.5 dark:bg-gray-700">
3
- <span class="absolute -top-6 left-0 text-sm text-gray-500">{{ leftLabel }}</span>
4
- <span class="absolute -top-6 right-0 text-sm text-gray-500">{{ rightLabel }}</span>
2
+ <div class="relative mt-4 lg:mt-10 w-full max-w-[700px] bg-lightProgressBarUnfilledColor rounded-full h-2.5 dark:bg-darkProgressBarUnfilledColor">
3
+ <span class="absolute -top-6 left-0 text-sm text-lightProgressBarText dark:text-darkProgressBarText">{{ leftLabel }}</span>
4
+ <span class="absolute -top-6 right-0 text-sm text-lightProgressBarText dark:text-darkProgressBarText">{{ rightLabel }}</span>
5
5
  <div
6
- class="bg-lightPrimary dark:bg-darkPrimary h-2.5 rounded-full transition-all duration-300 ease-in-out"
6
+ class="bg-lightProgressBarFilledColor dark:bg-darkProgressBarFilledColor h-2.5 rounded-full transition-all duration-300 ease-in-out"
7
7
  :style="{ width: `${percentage}%` }"
8
8
  ></div>
9
- <span v-if="showValues" class="absolute top-4 left-0 text-sm text-gray-500">{{ formatValue(minValue) }}</span>
10
- <span v-if="showProgress" class="absolute top-4 right-1/2 translate-x-1/2 text-sm text-gray-500">{{ progressText }}</span>
11
- <span v-if="showValues" class="absolute top-4 right-0 text-sm text-gray-500">{{ formatValue(maxValue) }}</span>
9
+ <span v-if="showValues" class="absolute top-4 left-0 text-sm text-lightProgressBarText dark:text-darkProgressBarText">{{ formatValue(minValue) }}</span>
10
+ <span v-if="showProgress" class="absolute top-4 right-1/2 translate-x-1/2 text-sm text-lightProgressBarText dark:text-darkProgressBarText">{{ progressText }}</span>
11
+ <span v-if="showValues" class="absolute top-4 right-0 text-sm text-lightProgressBarText dark:text-darkProgressBarText">{{ formatValue(maxValue) }}</span>
12
12
  </div>
13
13
  </template>
14
14
 
@@ -1,54 +1,57 @@
1
1
  <template>
2
- <div class="relative inline-block afcl-select" ref="internalSelect"
2
+ <div class="afcl-select afcl-select-wrapper relative inline-block" ref="internalSelect"
3
3
  :class="{'opacity-50': readonly}"
4
4
  >
5
5
  <div class="relative">
6
6
  <input
7
7
  ref="inputEl"
8
8
  type="text"
9
- :readonly="readonly"
9
+ :readonly="readonly || searchDisabled"
10
10
  v-model="search"
11
11
  @click="inputClick"
12
12
  @input="inputInput"
13
- class="block w-full pl-3 pr-10 py-2.5 border border-gray-300 rounded-md leading-5 bg-gray-50 placeholder-gray-500 sm:text-sm transition duration-150 ease-in-out dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white focus:ring-lightPrimary focus:border-lightPrimary dark:focus:ring-darkPrimary dark:focus:border-darkPrimary"
13
+ class="block w-full pl-3 pr-10 py-2.5 border border-lightDropownButtonsBorder rounded-md leading-5 bg-lightDropdownButtonsBackground
14
+ placeholder-lightDropdownButtonsPlaceholderText text-lightDropdownButtonsText sm:text-sm transition duration-150 ease-in-out dark:bg-darkDropdownButtonsBackground dark:border-darkDropdownButtonsBorder dark:placeholder-darkDropdownButtonsPlaceholderText
15
+ dark:text-darkDropdownButtonsText focus:ring-lightPrimary focus:border-lightPrimary dark:focus:ring-darkPrimary dark:focus:border-darkPrimary"
14
16
  autocomplete="off" data-custom="no-autofill"
15
17
  :placeholder="
16
18
  selectedItems.length && !multiple ? '' : (showDropdown ? $t('Search') : placeholder || $t('Select...'))
17
19
  "
18
20
  />
19
21
 
20
- <div v-if="!multiple && selectedItems.length" class="absolute pointer-events-none inset-y-0 left-2 flex items-center pr-2 px-1">
22
+ <div v-if="!multiple && selectedItems.length" class="text-lightDropdownButtonsText dark:text-darkDropdownButtonsText absolute pointer-events-none inset-y-0 left-2 flex items-center pr-2 px-1">
21
23
  <slot
22
24
  name="selected-item"
23
25
  :option="selectedItems[0]"
24
26
  ></slot>
25
- <span v-if="!$slots['selected-item']" class="text-lightPrimary dark:text-white font-medium ">
27
+ <span v-if="!$slots['selected-item']" class="text-lightDropdownButtonsText dark:text-darkDropdownButtonsText font-medium ">
26
28
  {{ selectedItems[0]?.label }}
27
29
  </span>
28
30
  </div>
29
31
 
30
32
  <div class="absolute inset-y-0 right-2 flex items-center pointer-events-none">
31
33
  <!-- triangle icon -->
32
- <IconCaretDownSolid class="h-5 w-5 text-lightPrimary dark:text-gray-400 opacity-50 transition duration-150 ease-in"
34
+ <IconCaretDownSolid class="h-5 w-5 text-lightPrimary dark:text-darkPrimary opacity-50 transition duration-150 ease-in"
33
35
  :class="{ 'transform rotate-180': showDropdown }"
34
36
  />
35
37
  </div>
36
38
  </div>
37
- <teleport to="body" v-if="teleportToBody && showDropdown">
38
- <div ref="dropdownEl" :style="getDropdownPosition" :class="{'shadow-none': isTop}"
39
- class="fixed z-[5] w-full bg-white shadow-lg dark:shadow-black dark:bg-gray-700
40
- dark:border-gray-600 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm max-h-48">
39
+ <teleport to="body" v-if="(teleportToBody || teleportToTop) && showDropdown">
40
+ <div ref="dropdownEl" :style="getDropdownPosition" :class="{'shadow-none': isTop, 'z-[5]': teleportToBody, 'z-[1000]': teleportToTop}"
41
+ class="fixed w-full bg-white shadow-lg dark:shadow-black dark:bg-gray-700
42
+ dark:border-gray-600 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm max-h-48"
43
+ @scroll="handleDropdownScroll">
41
44
  <div
42
45
  v-for="item in filteredItems"
43
46
  :key="item.value"
44
- class="px-4 py-2 cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-400"
45
- :class="{ 'bg-lightPrimaryOpacity dark:bg-darkPrimaryOpacity': selectedItems.includes(item) }"
47
+ class="px-4 py-2 cursor-pointer hover:bg-lightDropdownOptionsHoverBackground dark:hover:bg-darkDropdownOptionsHoverBackground text-lightDropdownOptionsText dark:text-darkDropdownOptionsText"
48
+ :class="{ 'bg-lightDropdownPicked dark:bg-darkDropdownPicked': selectedItems.includes(item) }"
46
49
  @click="toogleItem(item)"
47
50
  >
48
51
  <slot name="item" :option="item"></slot>
49
52
  <label v-if="!$slots.item" :for="item.value">{{ item.label }}</label>
50
53
  </div>
51
- <div v-if="!filteredItems.length" class="px-4 py-2 cursor-pointer text-gray-400 dark:text-gray-300">
54
+ <div v-if="!filteredItems.length" class="px-4 py-2 cursor-pointer text-lightDropdownOptionsText dark:text-darkDropdownOptionsText">
52
55
  {{ options.length ? $t('No results found') : $t('No items here') }}
53
56
  </div>
54
57
 
@@ -58,24 +61,24 @@
58
61
  </div>
59
62
  </teleport>
60
63
 
61
- <div v-if="!teleportToBody && showDropdown" ref="dropdownEl" :style="dropdownStyle" :class="{'shadow-none': isTop}"
62
- class="absolute z-10 mt-1 w-full bg-white shadow-lg dark:shadow-black dark:bg-gray-700
63
- dark:border-gray-600 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm max-h-48">
64
+ <div v-if="!teleportToBody && !teleportToTop && showDropdown" ref="dropdownEl" :style="dropdownStyle" :class="{'shadow-none': isTop}"
65
+ class="absolute z-10 mt-1 w-full bg-lightDropdownOptionsBackground shadow-lg text-lightDropdownButtonsText dark:shadow-black dark:bg-darkDropdownOptionsBackground
66
+ dark:border-gray-600 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm max-h-48"
67
+ @scroll="handleDropdownScroll">
64
68
  <div
65
69
  v-for="item in filteredItems"
66
70
  :key="item.value"
67
- class="px-4 py-2 cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-400"
68
- :class="{ 'bg-lightPrimaryOpacity dark:bg-darkPrimaryOpacity': selectedItems.includes(item) }"
71
+ class="px-4 py-2 cursor-pointer text-lightDropdownOptionsText hover:bg-lightDropdownOptionsHoverBackground dark:hover:bg-darkDropdownOptionsHoverBackground dark:text-darkDropdownOptionsText"
72
+ :class="{ 'bg-lightDropdownPicked dark:bg-darkDropdownPicked': selectedItems.includes(item) }"
69
73
  @click="toogleItem(item)"
70
74
  >
71
75
  <slot name="item" :option="item"></slot>
72
76
  <label v-if="!$slots.item" :for="item.value">{{ item.label }}</label>
73
77
  </div>
74
- <div v-if="!filteredItems.length" class="px-4 py-2 cursor-pointer text-gray-400 dark:text-gray-300">
78
+ <div v-if="!filteredItems.length" class="px-4 py-2 cursor-pointer text-lightDropdownOptionsText dark:text-darkDropdownOptionsText">
75
79
  {{ options.length ? $t('No results found') : $t('No items here') }}
76
80
  </div>
77
-
78
- <div v-if="$slots['extra-item']" class="px-4 py-2 dark:text-gray-400">
81
+ <div v-if="$slots['extra-item']" class="px-4 py-2 dark:text-darkDropdownOptionsText">
79
82
  <slot name="extra-item"></slot>
80
83
  </div>
81
84
 
@@ -87,12 +90,12 @@
87
90
  <template v-for="item in selectedItems" :key="`afcl-select-${item.value}`">
88
91
  <slot name="selected-item" :item="item"></slot>
89
92
  <div v-if="!$slots['selected-item']"
90
- class="bg-lightPrimaryOpacity text-lightPrimary text-xs font-medium me-2 px-2.5 py-0.5 rounded dark:bg-darkPrimaryOpacity dark:text-darkPrimary">
93
+ class="bg-lightDropdownMultipleSelectBackground text-lightDropdownMultipleSelectText text-xs font-medium me-2 px-2.5 py-0.5 rounded dark:bg-darkDropdownMultipleSelectBackground dark:text-darkDropdownMultipleSelectText">
91
94
  <span>{{ item.label }}</span>
92
95
  <button
93
96
  type="button"
94
97
  @click="toogleItem(item)"
95
- class="z-index-100 flex-shrink-0 ml-1 h-4 w-4 -mr-1 rounded-full inline-flex items-center justify-center text-gray-400 hover:text-gray-500 focus:outline-none focus:text-gray-500 focus:bg-gray-100"
98
+ class="z-index-100 flex-shrink-0 ml-1 h-4 w-4 -mr-1 rounded-full inline-flex items-center justify-center text-lightDropdownMultipleSelectIcon hover:text-lightDropdownMultipleSelectIconHover dark:text-darkDropdownMultipleSelectIcon dark:hover:text-darkDropdownMultipleSelectIconHover focus:outline-none focus:text-lightDropdownMultipleSelectIconFocus focus:bg-lightDropdownMultipleSelectIconFocusBackground dark:focus:text-darkDropdownMultipleSelectIconFocus dark:focus:bg-darkDropdownMultipleSelectIconFocusBackground"
96
99
  >
97
100
  <span class="sr-only">{{ $t('Remove item') }}</span>
98
101
  <svg class="h-2 w-2" stroke="currentColor" fill="none" viewBox="0 0 8 8">
@@ -111,7 +114,7 @@
111
114
  </template>
112
115
 
113
116
  <script setup lang="ts">
114
- import { ref, computed, onMounted, onUnmounted, watch, type Ref } from 'vue';
117
+ import { ref, computed, onMounted, onUnmounted, watch, nextTick, type Ref } from 'vue';
115
118
  import { IconCaretDownSolid } from '@iconify-prerendered/vue-flowbite';
116
119
  import { useElementSize } from '@vueuse/core'
117
120
 
@@ -132,13 +135,21 @@ const props = defineProps({
132
135
  type: Boolean,
133
136
  default: false,
134
137
  },
138
+ searchDisabled: {
139
+ type: Boolean,
140
+ default: false,
141
+ },
135
142
  teleportToBody: {
136
143
  type: Boolean,
137
144
  default: false,
138
145
  },
146
+ teleportToTop: {
147
+ type: Boolean,
148
+ default: false,
149
+ },
139
150
  });
140
151
 
141
- const emit = defineEmits(['update:modelValue']);
152
+ const emit = defineEmits(['update:modelValue', 'scroll-near-end', 'search']);
142
153
 
143
154
  const search = ref('');
144
155
  const showDropdown = ref(false);
@@ -159,6 +170,9 @@ function inputInput() {
159
170
  selectedItems.value = [];
160
171
  emit('update:modelValue', null);
161
172
  }
173
+ if (!props.searchDisabled) {
174
+ emit('search', search.value);
175
+ }
162
176
  }
163
177
 
164
178
  function updateFromProps() {
@@ -176,7 +190,7 @@ function updateFromProps() {
176
190
  }
177
191
  }
178
192
 
179
- function inputClick() {
193
+ async function inputClick() {
180
194
  if (props.readonly) return;
181
195
  // Toggle local dropdown
182
196
  showDropdown.value = !showDropdown.value;
@@ -184,6 +198,11 @@ function inputClick() {
184
198
  if (!showDropdown.value && !search.value) {
185
199
  search.value = '';
186
200
  }
201
+
202
+ if(props.teleportToBody){
203
+ await nextTick();
204
+ handleScroll();
205
+ }
187
206
  }
188
207
 
189
208
  watch(
@@ -221,6 +240,15 @@ const handleScroll = () => {
221
240
  }
222
241
  };
223
242
 
243
+ const handleDropdownScroll = (event: Event) => {
244
+ const target = event.target as HTMLElement;
245
+ const threshold = 10; // pixels from bottom
246
+
247
+ if (target.scrollTop + target.clientHeight >= target.scrollHeight - threshold) {
248
+ emit('scroll-near-end');
249
+ }
250
+ };
251
+
224
252
  onMounted(() => {
225
253
  updateFromProps();
226
254
 
@@ -241,7 +269,12 @@ onMounted(() => {
241
269
  });
242
270
 
243
271
  const filteredItems = computed(() => {
244
- return props.options.filter(item =>
272
+
273
+ if (props.searchDisabled) {
274
+ return props.options || [];
275
+ }
276
+
277
+ return (props.options || []).filter((item: any) =>
245
278
  item.label.toLowerCase().includes(search.value.toLowerCase())
246
279
  );
247
280
  });
@@ -1,20 +1,20 @@
1
1
  <template>
2
- <div v-if="type === 'image'" role="status" class="flex animate-pulse items-center justify-center bg-gray-300 rounded dark:bg-gray-700">
3
- <svg class="w-10 h-10 text-gray-200 dark:text-gray-600" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 18">
2
+ <div v-if="type === 'image'" role="status" class="flex animate-pulse items-center justify-center bg-lightSkeletonBackgroundColor rounded dark:bg-darkSkeletonBackgroundColor">
3
+ <svg class="w-10 h-10 text-lightSkeletonIconColor dark:text-darkSkeletonIconColor" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 18">
4
4
  <path d="M18 0H2a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2Zm-5.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3Zm4.376 10.481A1 1 0 0 1 16 15H4a1 1 0 0 1-.895-1.447l3.5-7A1 1 0 0 1 7.468 6a.965.965 0 0 1 .9.5l2.775 4.757 1.546-1.887a1 1 0 0 1 1.618.1l2.541 4a1 1 0 0 1 .028 1.011Z"/>
5
5
  </svg>
6
6
  </div>
7
- <div v-else-if="type === 'video'" role="status" class="flex items-center justify-center max-w-sm bg-gray-300 rounded-lg animate-pulse dark:bg-gray-700">
8
- <svg class="w-10 h-10 text-gray-200 dark:text-gray-600" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 16 20">
7
+ <div v-else-if="type === 'video'" role="status" class="flex items-center justify-center max-w-sm bg-lightSkeletonBackgroundColor rounded-lg animate-pulse dark:bg-darkSkeletonBackgroundColor">
8
+ <svg class="w-10 h-10 text-lightSkeletonIconColor dark:text-darkSkeletonIconColor" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 16 20">
9
9
  <path d="M5 5V.13a2.96 2.96 0 0 0-1.293.749L.879 3.707A2.98 2.98 0 0 0 .13 5H5Z"/>
10
10
  <path d="M14.066 0H7v5a2 2 0 0 1-2 2H0v11a1.97 1.97 0 0 0 1.934 2h12.132A1.97 1.97 0 0 0 16 18V2a1.97 1.97 0 0 0-1.934-2ZM9 13a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-2a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2Zm4 .382a1 1 0 0 1-1.447.894L10 13v-2l1.553-1.276a1 1 0 0 1 1.447.894v2.764Z"/>
11
11
  </svg>
12
12
  <span class="sr-only">Loading...</span>
13
13
  </div>
14
- <svg v-else-if="type === 'avatar'" class="me-3 animate-pulse text-gray-200 dark:text-gray-700" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20">
14
+ <svg v-else-if="type === 'avatar'" class="me-3 animate-pulse text-lightSkeletonIconColor dark:text-darkSkeletonBackgroundColor" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20">
15
15
  <path d="M10 0a10 10 0 1 0 10 10A10.011 10.011 0 0 0 10 0Zm0 5a3 3 0 1 1 0 6 3 3 0 0 1 0-6Zm0 13a8.949 8.949 0 0 1-4.951-1.488A3.987 3.987 0 0 1 9 13h2a3.987 3.987 0 0 1 3.951 3.512A8.949 8.949 0 0 1 10 18Z"/>
16
16
  </svg>
17
- <div v-else role="status" class="flex items-center justify-center animate-pulse bg-gray-200 rounded-full dark:bg-gray-700">
17
+ <div v-else role="status" class="flex items-center justify-center animate-pulse bg-lightSkeletonIconColor rounded-full dark:bg-darkSkeletonBackgroundColor">
18
18
  <span class="sr-only">Loading...</span>
19
19
  </div>
20
20
  </template>
@@ -1,8 +1,8 @@
1
1
  <template>
2
2
 
3
- <div class="relative overflow-x-auto shadow-md sm:rounded-lg">
4
- <table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
5
- <thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
3
+ <div class="afcl-table-container relative overflow-x-auto shadow-md sm:rounded-lg">
4
+ <table class="afcl-table w-full text-sm text-left rtl:text-right text-lightTableText dark:text-darkTableText">
5
+ <thead class="afcl-table-thread text-xs text-lightTableHeadingText uppercase bg-lightTableHeadingBackground dark:bg-darkTableHeadingBackground dark:text-darkTableHeadingText">
6
6
  <tr>
7
7
  <th scope="col" class="px-6 py-3"
8
8
  v-for="column in columns"
@@ -19,8 +19,8 @@
19
19
  <tr
20
20
  v-for="(item, index) in dataPage"
21
21
  :class="{
22
- 'odd:bg-white odd:dark:bg-gray-900 even:bg-gray-50 even:dark:bg-gray-800': evenHighlights,
23
- 'border-b dark:border-gray-700': index !== dataPage.length - 1 || totalPages > 1,
22
+ 'afcl-table-body odd:bg-lightTableOddBackground odd:dark:bg-darkTableOddBackground even:bg-lightTableEvenBackground even:dark:bg-darkTableEvenBackground': evenHighlights,
23
+ 'border-b border-lightTableBorder dark:border-darkTableBorder': index !== dataPage.length - 1 || totalPages > 1,
24
24
  }"
25
25
  >
26
26
  <td class="px-6 py-4"
@@ -38,25 +38,25 @@
38
38
  </tr>
39
39
  </tbody>
40
40
  </table>
41
- <nav class="flex items-center flex-column flex-wrap md:flex-row justify-between p-4"
41
+ <nav class="afcl-table-pagination-container bg-lightTableBackground dark:bg-darkTableBackground flex items-center flex-column flex-wrap md:flex-row justify-between p-4"
42
42
  v-if="totalPages > 1"
43
43
  :aria-label="$t('Table navigation')">
44
44
  <i18n-t
45
- keypath="Showing {from} to {to} of {total}" tag="span" class="text-sm font-normal text-gray-500 dark:text-gray-400 mb-4 md:mb-0 block w-full md:inline md:w-auto"
45
+ keypath="Showing {from} to {to} of {total}" tag="span" class="afcl-table-pagination-text text-sm font-normal text-lightTablePaginationText dark:text-darkTablePaginationText mb-4 md:mb-0 block w-full md:inline md:w-auto"
46
46
  >
47
- <template #from><span class="font-semibold text-gray-900 dark:text-white">{{ Math.min((currentPage - 1) * props.pageSize + 1, props.data.length) }}</span></template>
48
- <template #to><span class="font-semibold text-gray-900 dark:text-white">{{ Math.min(currentPage * props.pageSize, props.data.length) }}</span></template>
49
- <template #total><span class="font-semibold text-gray-900 dark:text-white">{{ props.data.length }}</span></template>
47
+ <template #from><span class="font-semibold text-lightTablePaginationNumeration dark:text-darkTablePaginationNumeration">{{ Math.min((currentPage - 1) * props.pageSize + 1, props.data.length) }}</span></template>
48
+ <template #to><span class="font-semibold text-lightTablePaginationNumeration dark:text-darkTablePaginationNumeration">{{ Math.min(currentPage * props.pageSize, props.data.length) }}</span></template>
49
+ <template #total><span class="font-semibold text-lightTablePaginationNumeration dark:text-darkTablePaginationNumeration">{{ props.data.length }}</span></template>
50
50
  </i18n-t>
51
51
 
52
- <ul class="inline-flex -space-x-px rtl:space-x-reverse text-sm h-8">
52
+ <ul class="afcl-table-pagination-list inline-flex -space-x-px rtl:space-x-reverse text-sm h-8">
53
53
  <li v-for="page in totalPages" :key="page">
54
54
  <a href="#"
55
55
  @click.prevent="switchPage(page)"
56
56
  :aria-current="page === page ? 'page' : undefined"
57
57
  :class='{
58
- "text-blue-600 bg-lightPrimary text-lightPrimaryContrast dark:bg-darkPrimary dark:text-darkPrimaryContrast hover:opacity-90": page === currentPage,
59
- "text-gray-500 border bg-white border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white": page !== currentPage,
58
+ "afcl-table-pagination-button text-blue-600 bg-lightActivePaginationButtonBackground text-lightActivePaginationButtonText dark:bg-darkActivePaginationButtonBackground dark:text-darkActivePaginationButtonText hover:opacity-90": page === currentPage,
59
+ "text-lightUnactivePaginationButtonText border bg-lightUnactivePaginationButtonBackground border-lightUnactivePaginationButtonBorder hover:bg-lightUnactivePaginationButtonHoverBackground hover:text-lightUnactivePaginationButtonHoverText dark:bg-darkUnactivePaginationButtonBackground dark:border-darkUnactivePaginationButtonBorder dark:text-darkUnactivePaginationButtonText dark:hover:bg-darkUnactivePaginationButtonHoverBackground dark:hover:text-darkUnactivePaginationButtonHoverText": page !== currentPage,
60
60
  "rounded-s-lg ms-0": page === 1,
61
61
  "rounded-e-lg": page === totalPages,
62
62
  }'
@@ -0,0 +1,31 @@
1
+ <template>
2
+
3
+ <textarea
4
+ ref="input"
5
+ class="bg-lightInputBackground border border-lightInputBorder text-lightInputText placeholder-lightInputPlaceholderText text-sm rounded-lg block w-full p-2.5 dark:bg-darkInputBackground dark:border-darkInputBorder dark:placeholder-darkInputPlaceholderText dark:text-darkInputText dark:border-darkInputBorder focus:ring-lightInputFocusRing focus:border-lightInputFocusBorder dark:focus:ring-darkInputFocusRing dark:focus:border-darkInputFocusBorder"
6
+ :placeholder="placeholder"
7
+ :value="modelValue"
8
+ @input="$emit('update:modelValue', ($event.target as HTMLInputElement).value)"
9
+ :readonly="readonly"
10
+ />
11
+
12
+ </template>
13
+
14
+ <script setup lang="ts">
15
+
16
+ import { ref } from 'vue';
17
+
18
+ const props = defineProps<{
19
+ modelValue: string,
20
+ readonly?: boolean,
21
+ placeholder?: string,
22
+ }>()
23
+
24
+ const input = ref<HTMLInputElement | null>(null)
25
+
26
+ defineExpose({
27
+ focus: () => input.value?.focus(),
28
+ });
29
+
30
+ </script>
31
+
@@ -0,0 +1,32 @@
1
+ <template>
2
+ <label class="inline-flex items-center cursor-pointer bor" :class="{'opacity-50' : props.disabled}">
3
+ <input :id="id"
4
+ type="checkbox"
5
+ value="" class="sr-only peer"
6
+ :disabled="props.disabled"
7
+ :checked="props.modelValue"
8
+ @change="$emit('update:modelValue', $event.target.checked)"
9
+ >
10
+ <div class="afcl-toggle border border-lightToggleBorderUnactive relative min-w-11 min-h-6 bg-lightToggleBgUnactive peer-focus:outline-none peer-focus:ring-4
11
+ peer-focus:ring-lightToggleRing dark:peer-focus:ring-darkToggleRing rounded-full peer dark:bg-darkToggleBgUnactive
12
+ peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:top-[2px] peer-checked:border-none
13
+ peer-checked:after:border-lightToggleBorderActive after:content-[''] after:absolute after:top-[1px]
14
+ after:start-[2px] after:bg-lightToggleCircleUnactive peer-checked:after:bg-lightToggleCircleActive dark:after:bg-darkToggleCircleUnactive after:border-lightToggleBgUnactive dark:after:border-darkToggleBgUnactive after:border after:rounded-full
15
+ after:h-5 after:w-5 after:transition-all dark:border-darkToggleBorderUnactive peer-checked:bg-lightToggleBgActive
16
+ dark:peer-checked:bg-darkToggleBgActive dark:peer-checked:after:border-darkToggleBorderActive dark:peer-checked:after:bg-darkToggleCircleActive">
17
+ </div>
18
+ <label :for="id" class="cursor-pointer ms-3 text-sm font-medium text-lightToggleText dark:text-darkToggleText">
19
+ <slot></slot>
20
+ </label>
21
+ </label>
22
+ </template>
23
+
24
+ <script setup lang="ts">
25
+ const props = defineProps({
26
+ modelValue: Boolean,
27
+ disabled: Boolean,
28
+ });
29
+
30
+ defineEmits(['update:modelValue']);
31
+ const id = `afcb-${Math.random().toString(36).substring(7)}`
32
+ </script>
@@ -1,16 +1,15 @@
1
1
  <template>
2
- <div ref="triggerEl" class="inline-flex items-center">
2
+ <div ref="triggerEl" class="afcl-tooltip inline-flex items-center">
3
3
  <slot></slot>
4
4
  </div>
5
5
  <div
6
6
  role="tooltip"
7
- class="absolute z-10 invisible inline-block px-3 py-2 text-sm font-medium text-white transition-opacity duration-300 bg-gray-900 rounded-lg shadow-sm opacity-0 tooltip dark:bg-gray-700"
7
+ class="absolute z-20 invisible inline-block px-3 py-2 text-sm font-medium text-lightTooltipText dark:darkTooltipText transition-opacity duration-300 bg-lightTooltipBackground rounded-lg shadow-sm opacity-0 tooltip dark:bg-darkTooltipBackground"
8
8
  ref="tooltip"
9
9
  >
10
10
  <slot name="tooltip"></slot>
11
11
  <div class="tooltip-arrow" data-popper-arrow></div>
12
12
  </div>
13
-
14
13
  </template>
15
14
 
16
15
  <script setup lang="ts">
@@ -1,19 +1,19 @@
1
1
  <template>
2
2
  <div class="md:flex">
3
- <ul class="flex-column space-y space-y-4 text-sm font-medium text-gray-500 dark:text-gray-400 md:me-4 mb-4 md:mb-0">
3
+ <ul class="flex-column space-y space-y-4 text-sm font-medium text-lightVerticalTabsText dark:text-darkVerticalTabsText md:me-4 mb-4 md:mb-0">
4
4
  <li v-for="tab in tabs" :key="`${tab}-tab-controll`">
5
5
  <a
6
6
  href="#"
7
7
  @click="activeTab = tab"
8
8
  class="inline-flex items-center px-4 py-3 rounded-lg w-full"
9
- :class="tab === activeTab ? 'text-lightPrimaryContrast bg-lightPrimary active dark:bg-darkPrimary' : 'text-gray-500 dark:text-gray-400 hover:text-gray-700 bg-gray-50 hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700 dark:hover:text-white'"
9
+ :class="tab === activeTab ? 'text-lightVerticalTabsTextActive bg-lightVerticalTabsBackgroundActive active dark:bg-darkVerticalTabsBackgroundActive dark:text-darkVerticalTabsTextActive' : 'text-lightVerticalTabsText dark:text-darkVerticalTabsText hover:text-lightVerticalTabsTextHover bg-lightVerticalTabsBackground hover:bg-lightVerticalTabsBackgroundHover dark:bg-darkVerticalTabsBackground dark:hover:bg-darkVerticalTabsBackgroundHover dark:hover:darkVerticalTabsTextHover'"
10
10
  aria-current="page"
11
11
  >
12
12
  <slot :name="`tab:${tab}`"></slot>
13
13
  </a>
14
14
  </li>
15
15
  </ul>
16
- <div class="ps-6 text-medium text-gray-500 dark:text-gray-400 w-full ">
16
+ <div class="ps-6 text-medium text-lightVerticalTabsSlotText dark:text-darkVerticalTabsSlotText w-full ">
17
17
  <slot :name="activeTab"></slot>
18
18
  </div>
19
19
  </div>
@@ -19,6 +19,7 @@ export { default as Skeleton } from './Skeleton.vue';
19
19
  export { default as Dialog } from './Dialog.vue';
20
20
  export { default as MixedChart } from './MixedChart.vue';
21
21
  export { default as CountryFlag } from './CountryFlag.vue';
22
-
23
-
24
-
22
+ export { default as JsonViewer } from './JsonViewer.vue';
23
+ export { default as Toggle } from './Toggle.vue';
24
+ export { default as DatePicker } from './DatePicker.vue';
25
+ export { default as Textarea } from './Textarea.vue';
@@ -6,24 +6,24 @@ const modalStore = useModalStore();
6
6
 
7
7
  <template>
8
8
  <Teleport to="body">
9
- <div v-if="modalStore.isOpened" class="bg-gray-900/50 dark:bg-gray-900/80 overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-full max-h-full">
9
+ <div v-if="modalStore.isOpened" class="bg-gray-900/50 dark:bg-gray-900/80 overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-[100] justify-center items-center w-full md:inset-0 h-full max-h-full">
10
10
  <div class="relative p-4 w-full max-w-md max-h-full top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 " >
11
- <div class="relative bg-white rounded-lg shadow dark:bg-gray-700 dark:shadow-black">
12
- <button type="button"@click="modalStore.togleModal" class="absolute top-3 end-2.5 text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white" >
11
+ <div class="afcl-confirmation-container relative bg-lightAcceptModalBackground rounded-lg shadow dark:bg-darkAcceptModalBackground dark:shadow-black">
12
+ <button type="button"@click="modalStore.togleModal" class="absolute top-3 end-2.5 text-lightAcceptModalCloseIcon bg-transparent hover:bg-lightAcceptModalCloseIconHoverBackground hover:text-lightAcceptModalCloseIconHover rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:text-darkAcceptModalCloseIcon dark:hover:bg-darkAcceptModalCloseIconHoverBackground dark:hover:text-darkAcceptModalCloseIconHover" >
13
13
  <svg class="w-3 h-3" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
14
14
  <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"/>
15
15
  </svg>
16
16
  <span class="sr-only">{{ $t('Close modal') }}</span>
17
17
  </button>
18
18
  <div class="p-4 md:p-5 text-center">
19
- <svg class="mx-auto mb-4 text-gray-400 w-12 h-12 dark:text-gray-200" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
19
+ <svg class="mx-auto mb-4 text-lightAcceptModalWarningIcon w-12 h-12 dark:text-darkAcceptModalWarningIcon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
20
20
  <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 11V6m0 8h.01M19 10a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/>
21
21
  </svg>
22
- <h3 class="mb-5 text-lg font-normal text-gray-500 dark:text-gray-400">{{ modalStore?.modalContent?.content }}</h3>
23
- <button @click="()=>{ modalStore.onAcceptFunction(true);modalStore.togleModal()}" type="button" class="text-white bg-red-600 hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 dark:focus:ring-red-800 font-medium rounded-lg text-sm inline-flex items-center px-5 py-2.5 text-center">
22
+ <h3 class="afcl-confirmation-title mb-5 text-lg font-normal text-lightAcceptModalText dark:text-darkAcceptModalText">{{ modalStore?.modalContent?.content }}</h3>
23
+ <button @click="()=>{ modalStore.onAcceptFunction(true);modalStore.togleModal()}" type="button" class="afcl-confirmation-accept-button text-lightAcceptModalConfirmButtonText bg-lightAcceptModalConfirmButtonBackground hover:bg-lightAcceptModalConfirmButtonBackgroundHover focus:ring-4 focus:outline-none focus:ring-lightAcceptModalConfirmButtonFocus font-medium rounded-lg text-sm inline-flex items-center px-5 py-2.5 text-center dark:text-darkAcceptModalConfirmButtonText dark:bg-darkAcceptModalConfirmButtonBackground dark:hover:bg-darkAcceptModalConfirmButtonBackgroundHover dark:focus:ring-darkAcceptModalConfirmButtonFocus">
24
24
  {{ modalStore?.modalContent?.acceptText }}
25
25
  </button>
26
- <button @click="()=>{modalStore.onAcceptFunction(false);modalStore.togleModal()}" type="button" class="py-2.5 px-5 ms-3 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-lightPrimary 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">{{ modalStore?.modalContent?.cancelText }}</button>
26
+ <button @click="()=>{modalStore.onAcceptFunction(false);modalStore.togleModal()}" type="button" class="afcl-confirmation-cancel-button py-2.5 px-5 ms-3 text-sm font-medium text-lightAcceptModalCancelButtonText focus:outline-none bg-lightAcceptModalCancelButtonBackground rounded-lg border border-lightAcceptModalCancelButtonBorder hover:bg-lightAcceptModalCancelButtonBackgroundHover hover:text-lightPrimary focus:z-10 focus:ring-4 focus:ring-lightAcceptModalCancelButtonFocus dark:focus:ring-darkAcceptModalCancelButtonFocus dark:bg-darkAcceptModalCancelButtonBackground dark:text-darkAcceptModalCancelButtonText dark:border-darkAcceptModalCancelButtonBorder dark:hover:text-darkAcceptModalCancelButtonTextHover dark:hover:bg-darkAcceptModalCancelButtonBackgroundHover">{{ modalStore?.modalContent?.cancelText }}</button>
27
27
  </div>
28
28
  </div>
29
29
  </div>
@@ -2,7 +2,7 @@
2
2
  <nav class="flex" 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-gray-700 hover:text-lightPrimary dark:text-gray-400 dark:hover:text-white">
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
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
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
8
  </svg>
@@ -11,19 +11,19 @@
11
11
  </li>
12
12
  <li>
13
13
  <div class="flex items-center">
14
- <svg class="rtl:rotate-180 w-3 h-3 text-gray-400 mx-1" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10">
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
15
  <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 9 4-4-4-4"/>
16
16
  </svg>
17
- <RouterLink :to="{name: 'resource-list', params: { resourceId: $route.params.resourceId }}" class="text-sm font-medium text-gray-500 md:ms-2 dark:text-gray-400">{{ coreStore.resourceById[$route.params.resourceId]?.label }}</RouterLink>
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>
18
18
  </div>
19
19
  </li>
20
20
 
21
21
  <li v-if="$route.params.primaryKey">
22
22
  <div class="flex items-center">
23
- <svg class="rtl:rotate-180 w-3 h-3 text-gray-400 mx-1" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10">
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
24
  <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 9 4-4-4-4"/>
25
25
  </svg>
26
- <span class="ms-1 text-sm font-medium text-gray-500 md:ms-2 dark:text-gray-400
26
+ <span class="ms-1 text-sm font-medium text-lightBreadcrumbsText md:ms-2 dark:text-darkBreadcrumbsText
27
27
  max-w-80 truncate">
28
28
  {{ $route.name === 'resource-edit' ? $t('Edit') : $t('Show') }} {{ coreStore.record?._label }}</span>
29
29
  </div>