@adminforth/universal-search 1.4.28 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build.log CHANGED
@@ -7,5 +7,5 @@ custom/
7
7
  custom/UniversalSearchInput.vue
8
8
  custom/tsconfig.json
9
9
 
10
- sent 2,945 bytes received 58 bytes 6,006.00 bytes/sec
11
- total size is 2,721 speedup is 0.91
10
+ sent 3,150 bytes received 58 bytes 6,416.00 bytes/sec
11
+ total size is 2,929 speedup is 0.91
@@ -1,57 +1,54 @@
1
1
  <template>
2
- <div class="af-universal-search flex items-center gap-1">
2
+ <!-- a narrow list header gives the search a full row, a wide one keeps it in its single row -->
3
+ <div class="af-universal-search flex w-full items-center gap-1 @4xl/header:w-auto">
3
4
  <slot name="prefix" />
4
- <div class="relative w-64">
5
- <input
5
+ <!-- enter is handled on the wrapper so it fires once: Input spreads attrs on both its root and the input -->
6
+ <div class="min-w-0 flex-1 @4xl/header:w-64 @4xl/header:flex-none" @keyup.enter="applyImmediate">
7
+ <Input
6
8
  v-model="localValue"
7
9
  type="text"
10
+ fullWidth
8
11
  :placeholder="props.meta?.placeholder ?? ''"
9
- class="w-full border rounded text-sm dark:bg-gray-800 border-gray-300 dark:border-gray-600 dark:text-white px-2 py-1 pr-6"
10
- @keyup.enter="applyImmediate"
11
12
  >
12
- <p
13
- v-if="localValue"
14
- @click="clear"
15
- class="absolute right-2 top-1/2 -translate-y-1/2 hover:cursor-pointer hover:text-gray-600 dark:text-white dark:hover:text-gray-400 "
16
- >
17
- ✕
18
- </p>
13
+ <template #rightIcon>
14
+ <IconX
15
+ v-if="localValue"
16
+ @click="clear"
17
+ class="w-4 h-4 cursor-pointer text-lightInputIconColor hover:text-lightInputText dark:text-darkInputIconColor dark:hover:text-darkInputText transition-colors"
18
+ />
19
+ </template>
20
+ </Input>
19
21
  </div>
20
22
  <slot name="suffix" />
21
23
  </div>
22
24
  </template>
23
25
  <script setup lang="ts">
24
- import { ref, watch, onMounted } from 'vue';
26
+ import { ref, computed, watch } from 'vue';
25
27
  import adminforth from '@/adminforth';
28
+ import { Input } from '@/afcl';
29
+ import { IconX } from '@iconify-prerendered/vue-lucide';
26
30
  import { AdminForthFilterOperators } from '@/types/Common';
27
- import { useRoute } from 'vue-router';
28
-
29
- const route = useRoute();
31
+ import { useFiltersStore } from '@/stores/filters';
30
32
 
31
33
  const props = defineProps<{ meta?: any; resource?: any; adminUser?: any }>();
32
- const localValue = ref('');
34
+ const filtersStore = useFiltersStore();
35
+ const field = '_universal_search';
36
+ const appliedTerm = computed(() => filtersStore.filters.find(f => f.field === field)?.value ?? '');
37
+ const localValue = ref(appliedTerm.value);
33
38
  let t: any = null;
34
39
  let blockFilterUpdate = false;
35
40
 
36
- onMounted(() => {
37
- const filters = Object.keys(route.query).filter(k => k.startsWith('filter__')).map(k => {
38
- const [_, field, operator] = k.split('__');
39
- return {
40
- field,
41
- operator,
42
- value: JSON.parse(decodeURIComponent(route.query[k] as string))
43
- }
44
- });
45
- const isUniversalSearchFilterApplied = filters.find(f => f.field === '_universal_search');
46
- if (isUniversalSearchFilterApplied) {
47
- localValue.value = isUniversalSearchFilterApplied.value;
41
+ // follow filter changes made outside of the input: restore from the URL, "clear filters"
42
+ watch(appliedTerm, (term) => {
43
+ if (term !== localValue.value.trim()) {
48
44
  blockFilterUpdate = true;
49
- };
45
+ localValue.value = term;
46
+ }
50
47
  });
51
48
 
52
49
  function send(term?: string) {
53
- adminforth?.list?.updateFilter?.({
54
- field: '_universal_search',
50
+ adminforth?.list?.setFilter?.({
51
+ field,
55
52
  operator: AdminForthFilterOperators.EQ,
56
53
  value: term || '',
57
54
  });
@@ -83,4 +80,4 @@ function clear() {
83
80
  localValue.value = '';
84
81
  applyImmediate();
85
82
  }
86
- </script>
83
+ </script>
@@ -1,57 +1,54 @@
1
1
  <template>
2
- <div class="af-universal-search flex items-center gap-1">
2
+ <!-- a narrow list header gives the search a full row, a wide one keeps it in its single row -->
3
+ <div class="af-universal-search flex w-full items-center gap-1 @4xl/header:w-auto">
3
4
  <slot name="prefix" />
4
- <div class="relative w-64">
5
- <input
5
+ <!-- enter is handled on the wrapper so it fires once: Input spreads attrs on both its root and the input -->
6
+ <div class="min-w-0 flex-1 @4xl/header:w-64 @4xl/header:flex-none" @keyup.enter="applyImmediate">
7
+ <Input
6
8
  v-model="localValue"
7
9
  type="text"
10
+ fullWidth
8
11
  :placeholder="props.meta?.placeholder ?? ''"
9
- class="w-full border rounded text-sm dark:bg-gray-800 border-gray-300 dark:border-gray-600 dark:text-white px-2 py-1 pr-6"
10
- @keyup.enter="applyImmediate"
11
12
  >
12
- <p
13
- v-if="localValue"
14
- @click="clear"
15
- class="absolute right-2 top-1/2 -translate-y-1/2 hover:cursor-pointer hover:text-gray-600 dark:text-white dark:hover:text-gray-400 "
16
- >
17
- ✕
18
- </p>
13
+ <template #rightIcon>
14
+ <IconX
15
+ v-if="localValue"
16
+ @click="clear"
17
+ class="w-4 h-4 cursor-pointer text-lightInputIconColor hover:text-lightInputText dark:text-darkInputIconColor dark:hover:text-darkInputText transition-colors"
18
+ />
19
+ </template>
20
+ </Input>
19
21
  </div>
20
22
  <slot name="suffix" />
21
23
  </div>
22
24
  </template>
23
25
  <script setup lang="ts">
24
- import { ref, watch, onMounted } from 'vue';
26
+ import { ref, computed, watch } from 'vue';
25
27
  import adminforth from '@/adminforth';
28
+ import { Input } from '@/afcl';
29
+ import { IconX } from '@iconify-prerendered/vue-lucide';
26
30
  import { AdminForthFilterOperators } from '@/types/Common';
27
- import { useRoute } from 'vue-router';
28
-
29
- const route = useRoute();
31
+ import { useFiltersStore } from '@/stores/filters';
30
32
 
31
33
  const props = defineProps<{ meta?: any; resource?: any; adminUser?: any }>();
32
- const localValue = ref('');
34
+ const filtersStore = useFiltersStore();
35
+ const field = '_universal_search';
36
+ const appliedTerm = computed(() => filtersStore.filters.find(f => f.field === field)?.value ?? '');
37
+ const localValue = ref(appliedTerm.value);
33
38
  let t: any = null;
34
39
  let blockFilterUpdate = false;
35
40
 
36
- onMounted(() => {
37
- const filters = Object.keys(route.query).filter(k => k.startsWith('filter__')).map(k => {
38
- const [_, field, operator] = k.split('__');
39
- return {
40
- field,
41
- operator,
42
- value: JSON.parse(decodeURIComponent(route.query[k] as string))
43
- }
44
- });
45
- const isUniversalSearchFilterApplied = filters.find(f => f.field === '_universal_search');
46
- if (isUniversalSearchFilterApplied) {
47
- localValue.value = isUniversalSearchFilterApplied.value;
41
+ // follow filter changes made outside of the input: restore from the URL, "clear filters"
42
+ watch(appliedTerm, (term) => {
43
+ if (term !== localValue.value.trim()) {
48
44
  blockFilterUpdate = true;
49
- };
45
+ localValue.value = term;
46
+ }
50
47
  });
51
48
 
52
49
  function send(term?: string) {
53
- adminforth?.list?.updateFilter?.({
54
- field: '_universal_search',
50
+ adminforth?.list?.setFilter?.({
51
+ field,
55
52
  operator: AdminForthFilterOperators.EQ,
56
53
  value: term || '',
57
54
  });
@@ -83,4 +80,4 @@ function clear() {
83
80
  localValue.value = '';
84
81
  applyImmediate();
85
82
  }
86
- </script>
83
+ </script>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adminforth/universal-search",
3
- "version": "1.4.28",
3
+ "version": "2.0.1",
4
4
  "description": "Universal quick search input plugin for AdminForth (injected before action buttons)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -50,12 +50,12 @@
50
50
  },
51
51
  "devDependencies": {
52
52
  "@types/node": "^22.18.6",
53
- "adminforth": "^3.7.1",
53
+ "adminforth": "^4.7.3",
54
54
  "semantic-release": "^24.2.9",
55
55
  "semantic-release-slack-bot": "^4.0.2",
56
56
  "typescript": "^5.9.2"
57
57
  },
58
58
  "peerDependencies": {
59
- "adminforth": "^3.7.1"
59
+ "adminforth": "^4.2.0"
60
60
  }
61
61
  }