v-nuxt-ui 0.2.34 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/components/AsyncSelect.vue +13 -2
  3. package/dist/runtime/components/ScrollArea.vue +2 -2
  4. package/dist/runtime/components/Select.vue +13 -2
  5. package/dist/runtime/components/Watermark.d.vue.ts +2 -2
  6. package/dist/runtime/components/Watermark.vue.d.ts +2 -2
  7. package/dist/runtime/components/button/Confirm.d.vue.ts +22 -0
  8. package/dist/runtime/components/button/Confirm.vue +47 -0
  9. package/dist/runtime/components/button/Confirm.vue.d.ts +22 -0
  10. package/dist/runtime/components/button/Theme.vue +7 -13
  11. package/dist/runtime/components/date-picker/Input.d.vue.ts +1 -0
  12. package/dist/runtime/components/date-picker/Input.vue +12 -3
  13. package/dist/runtime/components/date-picker/Input.vue.d.ts +1 -0
  14. package/dist/runtime/components/form/save-modal-template/WithApi.vue +1 -2
  15. package/dist/runtime/components/form/save-modal-template/index.vue +23 -23
  16. package/dist/runtime/components/layout/button/ThemePicker.vue +2 -2
  17. package/dist/runtime/components/layout/default.vue +10 -4
  18. package/dist/runtime/components/simple-table/index.d.vue.ts +1 -1
  19. package/dist/runtime/components/simple-table/index.vue +72 -1
  20. package/dist/runtime/components/simple-table/index.vue.d.ts +1 -1
  21. package/dist/runtime/components/sys/department/SaveModal.vue +0 -1
  22. package/dist/runtime/components/sys/flow/EditNodeModal.vue +5 -4
  23. package/dist/runtime/components/sys/flow/SaveModal.vue +0 -1
  24. package/dist/runtime/components/sys/menu/SaveModal.vue +0 -1
  25. package/dist/runtime/components/sys/role/SaveModal.vue +0 -1
  26. package/dist/runtime/components/sys/table/SaveModal.vue +0 -1
  27. package/dist/runtime/components/sys/table/TableColumnModal.vue +5 -4
  28. package/dist/runtime/components/sys/user/SaveModal.vue +0 -1
  29. package/dist/runtime/components/sys/user/Table.vue +19 -29
  30. package/dist/runtime/components/table/Page.vue +23 -2
  31. package/dist/runtime/components/table/Pagination.vue +1 -1
  32. package/dist/runtime/components/table/header/index.vue +231 -84
  33. package/dist/runtime/components/table/header/settings/columns/DndList.d.vue.ts +1 -0
  34. package/dist/runtime/components/table/header/settings/columns/DndList.vue +3 -1
  35. package/dist/runtime/components/table/header/settings/columns/DndList.vue.d.ts +1 -0
  36. package/dist/runtime/components/table/header/settings/columns/Item.d.vue.ts +1 -0
  37. package/dist/runtime/components/table/header/settings/columns/Item.vue +7 -3
  38. package/dist/runtime/components/table/header/settings/columns/Item.vue.d.ts +1 -0
  39. package/dist/runtime/components/table/header/settings/columns/index.d.vue.ts +3 -3
  40. package/dist/runtime/components/table/header/settings/columns/index.vue +7 -5
  41. package/dist/runtime/components/table/header/settings/columns/index.vue.d.ts +3 -3
  42. package/dist/runtime/components/table/header/settings/index.d.vue.ts +3 -2
  43. package/dist/runtime/components/table/header/settings/index.vue +5 -4
  44. package/dist/runtime/components/table/header/settings/index.vue.d.ts +3 -2
  45. package/dist/runtime/components/table/query/order/Newer.d.vue.ts +1 -0
  46. package/dist/runtime/components/table/query/order/Newer.vue +9 -2
  47. package/dist/runtime/components/table/query/order/Newer.vue.d.ts +1 -0
  48. package/dist/runtime/components/table/query/order/index.vue +46 -54
  49. package/dist/runtime/components/table/query/order/{Item.d.vue.ts → item.d.vue.ts} +2 -0
  50. package/dist/runtime/components/table/query/order/{Item.vue → item.vue} +25 -17
  51. package/dist/runtime/components/table/query/order/{Item.vue.d.ts → item.vue.d.ts} +2 -0
  52. package/dist/runtime/components/table/query/where/Newer.vue +2 -2
  53. package/dist/runtime/components/table/query/where/index.vue +90 -77
  54. package/dist/runtime/components/table/query/where/simple/item/ColumnPicker.vue +8 -7
  55. package/dist/runtime/components/table/query/where/simple/item/OprPicker.d.vue.ts +1 -0
  56. package/dist/runtime/components/table/query/where/simple/item/OprPicker.vue +6 -1
  57. package/dist/runtime/components/table/query/where/simple/item/OprPicker.vue.d.ts +1 -0
  58. package/dist/runtime/components/table/query/where/simple/item/index.d.vue.ts +3 -1
  59. package/dist/runtime/components/table/query/where/simple/item/index.vue +84 -39
  60. package/dist/runtime/components/table/query/where/simple/item/index.vue.d.ts +3 -1
  61. package/dist/runtime/components/table/query/where/simple/item/opr/AsyncSelect.vue +0 -1
  62. package/dist/runtime/components/table/query/where/simple/item/opr/DatePicker.d.vue.ts +1 -0
  63. package/dist/runtime/components/table/query/where/simple/item/opr/DatePicker.vue +42 -40
  64. package/dist/runtime/components/table/query/where/simple/item/opr/DatePicker.vue.d.ts +1 -0
  65. package/dist/runtime/components/table/query/where/simple/item/opr/Input.vue +3 -0
  66. package/dist/runtime/components/table/query/where/simple/item/opr/Select.vue +0 -1
  67. package/dist/runtime/components/table/query/where/simple/item/opr/index.vue +3 -0
  68. package/dist/runtime/composables/api/useApi.js +1 -0
  69. package/dist/runtime/composables/form/useForm.d.ts +2 -2
  70. package/dist/runtime/composables/form/useForm.js +10 -9
  71. package/dist/runtime/composables/table/useTable.js +9 -1
  72. package/dist/runtime/composables/table/useTableColumns.d.ts +1 -1
  73. package/dist/runtime/composables/table/useTableColumns.js +2 -2
  74. package/dist/runtime/composables/table/useTableQuery.d.ts +1 -0
  75. package/dist/runtime/composables/table/useTableQuery.js +8 -3
  76. package/dist/runtime/composables/table/useTableView.js +209 -11
  77. package/dist/runtime/composables/useTheme.js +10 -3
  78. package/dist/runtime/constants/columns.js +6 -6
  79. package/dist/runtime/types/components/form/index.d.ts +1 -1
  80. package/dist/runtime/types/components/table/column.d.ts +3 -1
  81. package/dist/runtime/types/components/table/header.d.ts +3 -1
  82. package/dist/runtime/types/components/table/query/order.d.ts +2 -0
  83. package/dist/runtime/types/components/table/query/where.d.ts +0 -1
  84. package/dist/runtime/types/query.d.ts +1 -0
  85. package/dist/runtime/types/storage.d.ts +1 -0
  86. package/package.json +1 -1
  87. package/dist/runtime/components/form/save-model-template/ConfirmUpdateModal.d.vue.ts +0 -19
  88. package/dist/runtime/components/form/save-model-template/ConfirmUpdateModal.vue +0 -111
  89. package/dist/runtime/components/form/save-model-template/ConfirmUpdateModal.vue.d.ts +0 -19
  90. package/dist/runtime/components/form/save-model-template/WithApi.d.vue.ts +0 -19
  91. package/dist/runtime/components/form/save-model-template/WithApi.vue +0 -37
  92. package/dist/runtime/components/form/save-model-template/WithApi.vue.d.ts +0 -19
  93. package/dist/runtime/components/form/save-model-template/index.d.vue.ts +0 -21
  94. package/dist/runtime/components/form/save-model-template/index.vue +0 -123
  95. package/dist/runtime/components/form/save-model-template/index.vue.d.ts +0 -21
@@ -85,41 +85,22 @@ const whereQueryWithoutInitValues = computed(() => {
85
85
  return !defaultKeys.includes(field);
86
86
  }) ?? [];
87
87
  });
88
- const whereQuerySectionExtraDataKey = "__whereQuerySection";
89
88
  function getBaseItemSection(item) {
90
89
  return props.whereOptions.find((opt) => opt.field === item.field)?.preferred === false ? "other" : "preferred";
91
90
  }
92
- function getItemSectionOverride(item) {
93
- if (!item.extraData || typeof item.extraData !== "object" || Array.isArray(item.extraData)) return void 0;
94
- const section = item.extraData[whereQuerySectionExtraDataKey];
95
- return section === "preferred" || section === "other" ? section : void 0;
96
- }
97
91
  function getItemSection(item) {
98
- return getItemSectionOverride(item) ?? getBaseItemSection(item);
92
+ const section = item.whereQuerySection;
93
+ return section === "preferred" || section === "other" ? section : getBaseItemSection(item);
99
94
  }
100
95
  function isPreferredItem(item) {
101
96
  return getItemSection(item) === "preferred";
102
97
  }
103
98
  function setItemSection(item, section) {
104
- const baseSection = getBaseItemSection(item);
105
- if (item.extraData && (typeof item.extraData !== "object" || Array.isArray(item.extraData))) {
106
- return item;
107
- }
108
- const extraData = item.extraData ? { ...item.extraData } : {};
109
- if (section === baseSection) {
110
- const { [whereQuerySectionExtraDataKey]: _section, ...restExtraData } = extraData;
111
- return {
112
- ...item,
113
- extraData: Object.keys(restExtraData).length > 0 ? restExtraData : void 0
114
- };
115
- } else {
116
- ;
117
- extraData[whereQuerySectionExtraDataKey] = section;
99
+ if (section === getBaseItemSection(item)) {
100
+ const { whereQuerySection: _omit, ...rest } = item;
101
+ return rest;
118
102
  }
119
- return {
120
- ...item,
121
- extraData: Object.keys(extraData).length > 0 ? extraData : void 0
122
- };
103
+ return { ...item, whereQuerySection: section };
123
104
  }
124
105
  const preferredItems = computed(
125
106
  () => whereQueryWithoutInitValues.value.filter(isPreferredItem)
@@ -133,18 +114,33 @@ watch([preferredItems, otherItems], () => {
133
114
  preferredDndItems.value = [...preferredItems.value];
134
115
  otherDndItems.value = [...otherItems.value];
135
116
  }, { immediate: true });
136
- function onDndEnd() {
117
+ function updateWhereQuerySections(preferred, other) {
137
118
  const defaultKeys = getDefaultKeys();
138
119
  const initItems = props.whereQuery?.items?.filter((q) => defaultKeys.includes(q.field)) ?? [];
139
120
  props.onUpdateWhereQuery({
140
121
  ...props.whereQuery,
141
122
  items: [
142
123
  ...initItems,
143
- ...preferredDndItems.value.map((item) => setItemSection(item, "preferred")),
144
- ...otherDndItems.value.map((item) => setItemSection(item, "other"))
124
+ ...preferred.map((item) => setItemSection(item, "preferred")),
125
+ ...other.map((item) => setItemSection(item, "other"))
145
126
  ]
146
127
  });
147
128
  }
129
+ function onDndEnd() {
130
+ updateWhereQuerySections(preferredDndItems.value, otherDndItems.value);
131
+ }
132
+ function onMoveItemSection(field, section) {
133
+ const currentPreferredItems = [...preferredDndItems.value];
134
+ const currentOtherItems = [...otherDndItems.value];
135
+ const sourceItems = section === "preferred" ? currentOtherItems : currentPreferredItems;
136
+ const item = sourceItems.find((item2) => item2.field === field);
137
+ if (!item) return;
138
+ const nextPreferredItems = section === "preferred" ? [...currentPreferredItems, item] : currentPreferredItems.filter((item2) => item2.field !== field);
139
+ const nextOtherItems = section === "other" ? [...currentOtherItems, item] : currentOtherItems.filter((item2) => item2.field !== field);
140
+ preferredDndItems.value = nextPreferredItems;
141
+ otherDndItems.value = nextOtherItems;
142
+ updateWhereQuerySections(nextPreferredItems, nextOtherItems);
143
+ }
148
144
  function onUpdateWhereQueryItem(field, newWhereQueryItem) {
149
145
  const items = props.whereQuery?.items ?? [];
150
146
  const realIdx = items.findIndex((query) => query.field === field);
@@ -172,7 +168,22 @@ const onClearValues = () => {
172
168
  });
173
169
  };
174
170
  const onResetAll = () => {
175
- props.onUpdateWhereQuery(props.defaultWhereQuery);
171
+ const currentItems = props.whereQuery?.items ?? [];
172
+ const currentFields = new Set(currentItems.map((item) => item.field));
173
+ const missingOptions = props.whereOptions.filter((opt) => !opt.initHide && !currentFields.has(opt.field));
174
+ const newItems = missingOptions.map((opt) => ({
175
+ field: opt.field,
176
+ opr: opt.defaultOpr ?? useTableOpr().getDefaultOprByType(opt.type),
177
+ value: null,
178
+ custom: opt.custom
179
+ }));
180
+ props.onUpdateWhereQuery({
181
+ ...props.whereQuery,
182
+ items: [
183
+ ...currentItems.map((item) => ({ ...item, value: null })),
184
+ ...newItems
185
+ ]
186
+ });
176
187
  };
177
188
  const onFillMissingFields = () => {
178
189
  const currentFields = new Set((props.whereQuery?.items ?? []).map((item) => item.field));
@@ -200,8 +211,8 @@ const onRemoveAllFields = () => {
200
211
  });
201
212
  };
202
213
  const moreActions = computed(() => [
203
- { label: "\u8865\u5168\u5B57\u6BB5", icon: "i-lucide-list-plus", onSelect: onFillMissingFields },
204
- { label: "\u5220\u9664\u6240\u6709\u5B57\u6BB5", icon: "i-lucide-trash-2", onSelect: onRemoveAllFields }
214
+ { label: "\u8865\u5168\u5168\u90E8\u5B57\u6BB5", icon: "i-lucide-list-plus", onSelect: onFillMissingFields },
215
+ { label: "\u6E05\u7A7A\u5168\u90E8\u5B57\u6BB5", icon: "i-lucide-trash-2", onSelect: onRemoveAllFields }
205
216
  ]);
206
217
  const focusField = (field) => {
207
218
  const item = itemRefMap.value.get(field);
@@ -211,65 +222,67 @@ const focusField = (field) => {
211
222
  }
212
223
  return false;
213
224
  };
214
- const conditionListClass = "grid grid-cols-24 gap-3";
225
+ const conditionListClass = "grid grid-cols-24 gap-2.5";
215
226
  const sections = reactive([
216
- { key: "preferred", label: "\u5E38\u7528\u6761\u4EF6", dndItems: preferredDndItems, unselectedFields: unselectedPreferredFields },
217
- { key: "other", label: "\u5176\u4ED6\u6761\u4EF6", dndItems: otherDndItems, unselectedFields: unselectedOtherFields }
227
+ { key: "preferred", label: "\u5E38\u7528\u67E5\u8BE2\u6761\u4EF6", dndItems: preferredDndItems, unselectedFields: unselectedPreferredFields },
228
+ { key: "other", label: "\u5176\u4ED6\u67E5\u8BE2\u6761\u4EF6", dndItems: otherDndItems, unselectedFields: unselectedOtherFields }
218
229
  ]);
219
230
  defineExpose({ focusField });
220
231
  </script>
221
232
 
222
233
  <template>
223
234
  <div class="divide-y divide-default">
224
- <div class="@container p-2.5 space-y-4">
225
- <div
235
+ <div class="@container p-4 space-y-6">
236
+ <template
226
237
  v-for="section in sections"
227
238
  :key="section.key"
228
239
  >
229
- <div class="font-bold text-xs text-dimmed mb-1.5">
230
- {{ section.label }}
231
- </div>
232
- <Dnd
233
- v-model="section.dndItems"
234
- group="where-query"
235
- handle=".where-query-handle"
236
- :on-end="onDndEnd"
237
- :class="conditionListClass"
238
- >
239
- <div
240
- v-for="item in section.dndItems"
241
- :key="item.field"
242
- class="flex items-center gap-1 col-span-24 @3xl:col-span-12 @5xl:col-span-8 @7xl:col-span-6"
243
- :class="isDateRangeQueryItem(item) ? '@3xl:col-span-24 @5xl:col-span-12 @7xl:col-span-8' : void 0"
244
- >
245
- <TableQueryWhereSimpleItem
246
- :ref="(el) => setItemRef(item.field, el)"
247
- :where-query-item="item"
248
- :options="whereOptions"
249
- :fetching="fetching"
250
- :trigger-fetching="() => triggerFetching(true)"
251
- handle-class-name="where-query-handle"
252
- @remove="onRemoveFilter"
253
- @update:where-query-item="(newWhereQueryItem) => onUpdateWhereQueryItem(item.field, newWhereQueryItem)"
254
- />
240
+ <div v-if="section.dndItems.length > 0">
241
+ <div class="font-bold text-xs text-dimmed mb-2.5">
242
+ {{ section.label }}
255
243
  </div>
256
- <div class="col-span-24 @3xl:col-span-12 @5xl:col-span-8 @7xl:col-span-6">
257
- <TableQueryWhereNewer
258
- v-if="unselectedWhereFields.length > 0"
259
- :options="whereOptions"
260
- :unselected-fields="unselectedWhereFields"
261
- :biz-columns="bizColumns ?? []"
262
- size="sm"
263
- @new="onNewField"
264
- />
265
- </div>
266
- </Dnd>
267
- </div>
244
+ <Dnd
245
+ v-model="section.dndItems"
246
+ group="where-query"
247
+ handle=".where-query-handle"
248
+ :on-end="onDndEnd"
249
+ :class="conditionListClass"
250
+ >
251
+ <div
252
+ v-for="item in section.dndItems"
253
+ :key="item.field"
254
+ class="col-span-24 @2xl:col-span-12 @4xl:col-span-8 @6xl:col-span-6 @7xl:col-span-4"
255
+ :class="isDateRangeQueryItem(item) ? '@2xl:col-span-24 @4xl:col-span-12 @6xl:col-span-8 @7xl:col-span-6' : void 0"
256
+ >
257
+ <TableQueryWhereSimpleItem
258
+ :ref="(el) => setItemRef(item.field, el)"
259
+ :where-query-item="item"
260
+ :options="whereOptions"
261
+ :fetching="fetching"
262
+ :trigger-fetching="() => triggerFetching(true)"
263
+ handle-class-name="where-query-handle"
264
+ :section="section.key"
265
+ @remove="onRemoveFilter"
266
+ @move-section="onMoveItemSection"
267
+ @update:where-query-item="(newWhereQueryItem) => onUpdateWhereQueryItem(item.field, newWhereQueryItem)"
268
+ />
269
+ </div>
270
+ </Dnd>
271
+ </div>
272
+ </template>
268
273
  </div>
269
274
  <!-- action bar -->
270
- <div class="flex items-center gap-2.5 p-2.5">
275
+ <div class="flex items-center gap-2.5 p-4">
271
276
  <div class="flex-1" />
272
277
  <div class="flex items-center gap-2.5">
278
+ <TableQueryWhereNewer
279
+ v-if="unselectedWhereFields.length > 0"
280
+ :options="whereOptions"
281
+ :unselected-fields="unselectedWhereFields"
282
+ :biz-columns="bizColumns ?? []"
283
+ size="sm"
284
+ @new="onNewField"
285
+ />
273
286
  <UButton
274
287
  v-if="!hideQueryButton"
275
288
  label="查询"
@@ -302,9 +315,9 @@ defineExpose({ focusField });
302
315
  :disabled="fetching"
303
316
  @click="onResetAll"
304
317
  >
305
- 还原默认
318
+ 恢复默认条件
306
319
  </UButton>
307
- <UDropdownMenu :items="moreActions">
320
+ <UDropdownMenu :items="moreActions" size="sm">
308
321
  <UButton
309
322
  color="neutral"
310
323
  variant="subtle"
@@ -32,14 +32,14 @@ const items = computed(() => {
32
32
  });
33
33
  const result = [];
34
34
  if (commonItems.length > 0) {
35
- result.push({ type: "label", label: "\u5E38\u7528\u6761\u4EF6" });
35
+ result.push({ type: "label", label: "\u5E38\u7528\u67E5\u8BE2\u6761\u4EF6" });
36
36
  result.push(...commonItems);
37
37
  }
38
38
  if (otherItems.length > 0) {
39
39
  if (result.length > 0) {
40
40
  result.push({ type: "separator" });
41
41
  }
42
- result.push({ type: "label", label: "\u5176\u4ED6\u6761\u4EF6" });
42
+ result.push({ type: "label", label: "\u5176\u4ED6\u67E5\u8BE2\u6761\u4EF6" });
43
43
  result.push(...otherItems);
44
44
  }
45
45
  return result;
@@ -72,14 +72,15 @@ const currentOption = computed(() => {
72
72
  :items="items"
73
73
  >
74
74
  <UButton
75
- :size="'sm'"
76
- :color="'neutral'"
77
- :variant="'outline'"
75
+ size="sm"
76
+ color="neutral"
77
+ variant="ghost"
78
+ :icon="tableWhereQueryItemIconMap.get(currentOption?.type ?? 'unknown') || 'field'"
78
79
  :label="currentOption?.label || '\u9009\u62E9\u5B57\u6BB5'"
79
80
  :disabled="disabled"
80
- :icon="tableWhereQueryItemIconMap.get(currentOption?.type ?? 'unknown') || 'field'"
81
81
  :ui="{
82
- label: 'font-bold'
82
+ base: 'w-full rounded-b-none',
83
+ label: 'font-bold text-highlighted'
83
84
  }"
84
85
  />
85
86
  </ButtonDropdown>
@@ -4,6 +4,7 @@ declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_se
4
4
  options: WhereQueryOption<T>[];
5
5
  disabled?: boolean;
6
6
  focus?: () => void;
7
+ buttonClass?: string;
7
8
  } & {
8
9
  whereQueryItem: WhereQueryItem<T>;
9
10
  }) & {
@@ -5,7 +5,8 @@ import ButtonDropdown from "#v/components/button/Dropdown.vue";
5
5
  const props = defineProps({
6
6
  options: { type: Array, required: true },
7
7
  disabled: { type: Boolean, required: false },
8
- focus: { type: Function, required: false }
8
+ focus: { type: Function, required: false },
9
+ buttonClass: { type: String, required: false }
9
10
  });
10
11
  const whereQueryItem = defineModel("whereQueryItem", { type: Object, ...{ required: true } });
11
12
  const option = computed(
@@ -57,6 +58,10 @@ const currentLabel = computed(() => {
57
58
  variant="outline"
58
59
  :label="currentLabel"
59
60
  :disabled="disabled"
61
+ :ui="{
62
+ base: 'rounded-t-none',
63
+ label: 'text-dimmed'
64
+ }"
60
65
  />
61
66
  </ButtonDropdown>
62
67
  </template>
@@ -4,6 +4,7 @@ declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_se
4
4
  options: WhereQueryOption<T>[];
5
5
  disabled?: boolean;
6
6
  focus?: () => void;
7
+ buttonClass?: string;
7
8
  } & {
8
9
  whereQueryItem: WhereQueryItem<T>;
9
10
  }) & {
@@ -6,10 +6,12 @@ declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_se
6
6
  triggerFetching?: () => Promise<void>;
7
7
  onRemove: (field: string) => void;
8
8
  handleClassName?: string;
9
+ section: "preferred" | "other";
9
10
  } & {
10
11
  whereQueryItem: WhereQueryItem<T>;
11
12
  }) & {
12
13
  "onUpdate:whereQueryItem"?: ((value: WhereQueryItem<T>) => any) | undefined;
14
+ onMoveSection?: ((field: string, section: "preferred" | "other") => any) | undefined;
13
15
  }> & (typeof globalThis extends {
14
16
  __VLS_PROPS_FALLBACK: infer P;
15
17
  } ? P : {});
@@ -18,7 +20,7 @@ declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_se
18
20
  }>) => void;
19
21
  attrs: any;
20
22
  slots: {};
21
- emit: (event: "update:whereQueryItem", value: WhereQueryItem<T>) => void;
23
+ emit: ((evt: "moveSection", field: string, section: "preferred" | "other") => void) & ((event: "update:whereQueryItem", value: WhereQueryItem<T>) => void);
22
24
  }>) => import("vue").VNode & {
23
25
  __ctx?: Awaited<typeof __VLS_setup>;
24
26
  };
@@ -1,17 +1,45 @@
1
1
  <script setup>
2
- import { computed, watch, useTemplateRef } from "vue";
3
- import TableQueryWhereSimpleItemColumnPicker from "#v/components/table/query/where/simple/item/ColumnPicker.vue";
2
+ import { computed, shallowRef, watch, useTemplateRef } from "vue";
4
3
  import TableQueryWhereSimpleItemOprPicker from "#v/components/table/query/where/simple/item/OprPicker.vue";
5
4
  import TableQueryWhereSimpleItemOpr from "#v/components/table/query/where/simple/item/opr/index.vue";
5
+ import ButtonConfirm from "#v/components/button/Confirm.vue";
6
+ import { tableWhereQueryItemIconMap } from "#v/constants";
6
7
  const props = defineProps({
7
8
  options: { type: Array, required: true },
8
9
  fetching: { type: Boolean, required: false },
9
10
  triggerFetching: { type: Function, required: false },
10
11
  onRemove: { type: Function, required: true },
11
- handleClassName: { type: String, required: false }
12
+ handleClassName: { type: String, required: false },
13
+ section: { type: String, required: true }
12
14
  });
15
+ const emit = defineEmits(["moveSection"]);
13
16
  const whereQueryItem = defineModel("whereQueryItem", { type: Object, ...{ required: true } });
14
17
  const option = computed(() => props.options.find((option2) => option2.field === whereQueryItem.value.field));
18
+ const moveMenuOpen = shallowRef(false);
19
+ const pointerStart = shallowRef(null);
20
+ const moveSectionItems = computed(() => {
21
+ const targetSection = props.section === "preferred" ? "other" : "preferred";
22
+ return [{
23
+ label: props.section === "preferred" ? "\u79FB\u52A8\u5230\u5176\u4ED6\u67E5\u8BE2\u6761\u4EF6" : "\u79FB\u52A8\u5230\u5E38\u7528\u67E5\u8BE2\u6761\u4EF6",
24
+ icon: props.section === "preferred" ? "i-lucide-folder-input" : "i-lucide-star",
25
+ onSelect: () => emit("moveSection", whereQueryItem.value.field, targetSection)
26
+ }];
27
+ });
28
+ function onHandlePointerDown(event) {
29
+ pointerStart.value = event;
30
+ }
31
+ function onHandlePointerUp(event) {
32
+ if (!pointerStart.value) return;
33
+ const distance = Math.hypot(
34
+ event.clientX - pointerStart.value.clientX,
35
+ event.clientY - pointerStart.value.clientY
36
+ );
37
+ pointerStart.value = null;
38
+ if (distance > 4) return;
39
+ window.setTimeout(() => {
40
+ moveMenuOpen.value = !moveMenuOpen.value;
41
+ });
42
+ }
15
43
  watch(
16
44
  () => option.value?.custom,
17
45
  (newCustom) => {
@@ -27,40 +55,57 @@ defineExpose({
27
55
  </script>
28
56
 
29
57
  <template>
30
- <UFieldGroup size="sm" class="w-full">
31
- <UButton
32
- variant="outline"
33
- icon="i-lucide-grip-vertical"
34
- color="neutral"
35
- :class="handleClassName"
36
- />
37
- <TableQueryWhereSimpleItemColumnPicker
38
- v-model:where-query-item="whereQueryItem"
39
- :options="options"
40
- :fetching="fetching"
41
- disabled
42
- :focus="() => oprRef?.focus()"
43
- />
44
- <TableQueryWhereSimpleItemOprPicker
45
- v-model:where-query-item="whereQueryItem"
46
- :options="options"
47
- :fetching="fetching"
48
- :focus="() => oprRef?.focus()"
49
- :disabled="option?.disableOprSelector"
50
- />
51
- <TableQueryWhereSimpleItemOpr
52
- ref="opr"
53
- v-model:where-query-item="whereQueryItem"
54
- :options="options"
55
- :fetching="fetching"
56
- :trigger-fetching="triggerFetching"
57
- class="w-full"
58
- />
59
- <UButton
60
- color="neutral"
61
- variant="outline"
62
- icon="i-lucide-x"
63
- @click="onRemove(whereQueryItem.field)"
64
- />
65
- </UFieldGroup>
58
+ <div class="w-full flex flex-col group/where-item">
59
+ <div class="flex items-center rounded-t-md bg-elevated/40 border border-b-0 border-accented">
60
+ <!-- <TableQueryWhereSimpleItemColumnPicker
61
+ v-model:where-query-item="whereQueryItem"
62
+ :options="options"
63
+ :fetching="fetching"
64
+ disabled
65
+ class="!bg-elevated/40"
66
+ :focus="() => oprRef?.focus()"
67
+ /> -->
68
+ <div class="flex-1 flex items-center gap-1 pl-2.5">
69
+ <UIcon :name="tableWhereQueryItemIconMap.get(option?.type ?? 'unknown') || 'field'" class="size-3.5 text-highlighted" />
70
+ <span class="text-xs font-bold text-highlighted">
71
+ {{ option?.label ?? whereQueryItem.field }}
72
+ </span>
73
+ </div>
74
+ <ButtonConfirm
75
+ class="rounded-br-none opacity-0 transition-all group-hover/where-item:opacity-100 max-md:opacity-100"
76
+ @confirm="onRemove(whereQueryItem.field)"
77
+ />
78
+ </div>
79
+ <UFieldGroup size="sm" class="w-full">
80
+ <TableQueryWhereSimpleItemOprPicker
81
+ v-model:where-query-item="whereQueryItem"
82
+ :options="options"
83
+ :fetching="fetching"
84
+ :focus="() => oprRef?.focus()"
85
+ :disabled="option?.disableOprSelector"
86
+ button-class="rounded-t-none bg-default text-muted font-normal"
87
+ />
88
+ <TableQueryWhereSimpleItemOpr
89
+ ref="opr"
90
+ v-model:where-query-item="whereQueryItem"
91
+ :options="options"
92
+ :fetching="fetching"
93
+ :trigger-fetching="triggerFetching"
94
+ class="w-full"
95
+ />
96
+ <UDropdownMenu v-model:open="moveMenuOpen" :items="moveSectionItems" size="sm">
97
+ <UButton
98
+ variant="outline"
99
+ icon="i-lucide-grip-vertical"
100
+ color="neutral"
101
+ class="cursor-move hover:bg-default active:bg-default rounded-t-none"
102
+ :class="handleClassName"
103
+ aria-label="拖拽或移动查询条件分组"
104
+ @pointerdown="onHandlePointerDown"
105
+ @pointerup="onHandlePointerUp"
106
+ @pointercancel="pointerStart = null"
107
+ />
108
+ </UDropdownMenu>
109
+ </UFieldGroup>
110
+ </div>
66
111
  </template>
@@ -6,10 +6,12 @@ declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_se
6
6
  triggerFetching?: () => Promise<void>;
7
7
  onRemove: (field: string) => void;
8
8
  handleClassName?: string;
9
+ section: "preferred" | "other";
9
10
  } & {
10
11
  whereQueryItem: WhereQueryItem<T>;
11
12
  }) & {
12
13
  "onUpdate:whereQueryItem"?: ((value: WhereQueryItem<T>) => any) | undefined;
14
+ onMoveSection?: ((field: string, section: "preferred" | "other") => any) | undefined;
13
15
  }> & (typeof globalThis extends {
14
16
  __VLS_PROPS_FALLBACK: infer P;
15
17
  } ? P : {});
@@ -18,7 +20,7 @@ declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_se
18
20
  }>) => void;
19
21
  attrs: any;
20
22
  slots: {};
21
- emit: (event: "update:whereQueryItem", value: WhereQueryItem<T>) => void;
23
+ emit: ((evt: "moveSection", field: string, section: "preferred" | "other") => void) & ((event: "update:whereQueryItem", value: WhereQueryItem<T>) => void);
22
24
  }>) => import("vue").VNode & {
23
25
  __ctx?: Awaited<typeof __VLS_setup>;
24
26
  };
@@ -54,6 +54,5 @@ defineExpose({
54
54
  v-bind="props"
55
55
  v-model="modelValue"
56
56
  :placeholder="`\u8BF7\u9009\u62E9${label ?? ''}`"
57
- rounded-none
58
57
  />
59
58
  </template>
@@ -2,6 +2,7 @@ import type { WhereQueryItem } from '#v/types';
2
2
  declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
3
3
  props: import("vue").PublicProps & __VLS_PrettifyLocal<({
4
4
  disabled?: boolean;
5
+ roundedNone?: boolean;
5
6
  } & {
6
7
  whereQueryItem: WhereQueryItem<T>;
7
8
  }) & {
@@ -7,7 +7,8 @@ import { useApp } from "#v/composables/useApp";
7
7
  import { TIME_ZONE } from "#v/constants";
8
8
  import DatePickerInput from "#v/components/date-picker/Input.vue";
9
9
  defineProps({
10
- disabled: { type: Boolean, required: false }
10
+ disabled: { type: Boolean, required: false },
11
+ roundedNone: { type: Boolean, required: false }
11
12
  });
12
13
  const whereQueryItem = defineModel("whereQueryItem", { type: Object, ...{ required: true } });
13
14
  const app = useApp();
@@ -57,7 +58,6 @@ const calendarValue = computed({
57
58
  });
58
59
  const displayDateFormat = "YYYY-MM-DD";
59
60
  const startDateStrValueInput = useTemplateRef("startDateStrValueInput");
60
- const endDateStrValueInput = useTemplateRef("endDateStrValueInput");
61
61
  const startDateStrValue = computed({
62
62
  get() {
63
63
  return useDate().dateValueToDayjs(calendarValue.value?.start)?.format(displayDateFormat) ?? void 0;
@@ -150,54 +150,56 @@ const dateRangeShortcuts = [
150
150
  onOpenAutoFocus: (e) => e.preventDefault()
151
151
  }"
152
152
  >
153
- <!-- 输入框直接暴露 -->
154
- <template v-if="isNoCalendarOpr" />
153
+ <!--
154
+ 使用 anchor 插槽而非默认(trigger)插槽来承载输入框:
155
+ UPopover 的 trigger(mode="click")会把 onClick 切换逻辑及 aria 属性
156
+ 合并到插槽根元素上,若输入框直接作为根元素,会与 focus 打开逻辑冲突
157
+ (弹层一闪即关)并污染 input。anchor 只负责定位,不带点击切换。
158
+ -->
159
+ <template #anchor>
160
+ <span v-if="isNoCalendarOpr" />
155
161
 
156
- <UFieldGroup
157
- v-else-if="isRangeOpr"
158
- class="w-full"
159
- >
160
- <div />
161
- <DatePickerInput
162
- ref="startDateStrValueInput"
163
- v-model:value="startDateStrValue"
164
- icon=""
165
- input-class="min-w-28 flex-1"
166
- placeholder="YYYY-MM-DD"
167
- @focus="onOpenCalendar"
168
- @blur="onCloseCalendar"
169
- />
170
- <UBadge variant="outline" color="neutral">
171
- ~
172
- </UBadge>
173
- <DatePickerInput
174
- ref="endDateStrValueInput"
175
- v-model:value="endDateStrValue"
176
- icon=""
177
- input-class="min-w-28 flex-1"
178
- placeholder="YYYY-MM-DD"
179
- @focus="onOpenCalendar"
180
- @blur="onCloseCalendar"
181
- />
182
- <div />
183
- </UFieldGroup>
162
+ <UFieldGroup
163
+ v-else-if="isRangeOpr"
164
+ class="w-full"
165
+ >
166
+ <DatePickerInput
167
+ ref="startDateStrValueInput"
168
+ v-model:value="startDateStrValue"
169
+ icon=""
170
+ input-class="flex-1"
171
+ :rounded-none="roundedNone"
172
+ placeholder="YYYY-MM-DD"
173
+ @focus="onOpenCalendar"
174
+ @blur="onCloseCalendar"
175
+ />
176
+ <UBadge variant="outline" color="neutral">
177
+ ~
178
+ </UBadge>
179
+ <DatePickerInput
180
+ ref="endDateStrValueInput"
181
+ v-model:value="endDateStrValue"
182
+ icon=""
183
+ input-class="flex-1"
184
+ :rounded-none="roundedNone"
185
+ placeholder="YYYY-MM-DD"
186
+ @focus="onOpenCalendar"
187
+ @blur="onCloseCalendar"
188
+ />
189
+ </UFieldGroup>
184
190
 
185
- <div
186
- v-else
187
- class="w-full"
188
- >
189
- <div />
190
191
  <DatePickerInput
192
+ v-else
191
193
  ref="singleDateStrValueInput"
192
194
  v-model:value="singleDateStrValue"
193
195
  icon=""
194
- input-class="w-full min-w-32"
196
+ input-class="w-full"
197
+ :rounded-none="roundedNone"
195
198
  placeholder="YYYY-MM-DD"
196
199
  @focus="onOpenCalendar"
197
200
  @blur="onCloseCalendar"
198
201
  />
199
- <div />
200
- </div>
202
+ </template>
201
203
 
202
204
  <template #content>
203
205
  <div
@@ -2,6 +2,7 @@ import type { WhereQueryItem } from '#v/types';
2
2
  declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
3
3
  props: import("vue").PublicProps & __VLS_PrettifyLocal<({
4
4
  disabled?: boolean;
5
+ roundedNone?: boolean;
5
6
  } & {
6
7
  whereQueryItem: WhereQueryItem<T>;
7
8
  }) & {