@bagelink/vue 1.9.69 → 1.9.73

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.
@@ -1 +1 @@
1
- {"version":3,"file":"dateUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/calendar/dateUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,KAAK,EAAE,uBAAuB,EAAY,MAAM,sBAAsB,CAAA;AAG7E,UAAU,gBAAgB;IACzB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;CACb;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,gBAAgB,QA+BvE;AAED,KAAK,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AA2E1D,wBAAgB,OAAO,CACtB,IAAI,EAAE,MAAM,GAAG,IAAI,EACnB,YAAY,CAAC,EAAE,WAAW,GAAG;IAAE,IAAI,CAAC,EAAE,WAAW,CAAC;IAAC,IAAI,CAAC,EAAE,UAAU,GAAG,UAAU,CAAA;CAAE,UA0EnF;AAsBD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,qBAAqB,GAAG,IAAI,CA2CtF;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,CAAC,EAAE,IAAI,CAAC,qBAAqB;;;;;;;;;;;;;;EAyB/G;AAcD,MAAM,WAAW,iBAAkB,SAAQ,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,QAAQ,CAAC,CAAC;IAC7F,MAAM,CAAC,EAAE,uBAAuB,CAAA;IAChC,MAAM,CAAC,EAAE,IAAI,CAAC,eAAe,CAAA;IAC7B,EAAE,CAAC,EAAE,MAAM,CAAA;CACX;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,uBAAuB,GAAG,MAAM,CAAA;AAErF;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAAA;AAkG7E,eAAO,MAAM,OAAO,mBAAa,CAAA"}
1
+ {"version":3,"file":"dateUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/calendar/dateUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,KAAK,EAAE,uBAAuB,EAAY,MAAM,sBAAsB,CAAA;AAG7E,UAAU,gBAAgB;IACzB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;CACb;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,gBAAgB,QA+BvE;AAED,KAAK,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AA2E1D,wBAAgB,OAAO,CACtB,IAAI,EAAE,MAAM,GAAG,IAAI,EACnB,YAAY,CAAC,EAAE,WAAW,GAAG;IAAE,IAAI,CAAC,EAAE,WAAW,CAAC;IAAC,IAAI,CAAC,EAAE,UAAU,GAAG,UAAU,CAAA;CAAE,UA0EnF;AAsBD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,qBAAqB,GAAG,IAAI,CA2CtF;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,CAAC,EAAE,IAAI,CAAC,qBAAqB;;;;;;;;;;;;;;EAyB/G;AAcD,MAAM,WAAW,iBAAkB,SAAQ,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,QAAQ,CAAC,CAAC;IAC7F,MAAM,CAAC,EAAE,uBAAuB,CAAA;IAChC,MAAM,CAAC,EAAE,IAAI,CAAC,eAAe,CAAA;IAC7B,EAAE,CAAC,EAAE,MAAM,CAAA;CACX;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,uBAAuB,GAAG,MAAM,CAAA;AAErF;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAAA;AAyG7E,eAAO,MAAM,OAAO,mBAAa,CAAA"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bagelink/vue",
3
3
  "type": "module",
4
- "version": "1.9.69",
4
+ "version": "1.9.73",
5
5
  "description": "Bagel core sdk packages",
6
6
  "author": {
7
7
  "name": "Bagel Studio",
@@ -2,7 +2,7 @@
2
2
  import type { Option } from '@bagelink/vue'
3
3
  import type { ComparisonOperator, LogicalOperator, QueryConditions } from '../utils/queryFilter'
4
4
  import { Btn, DateInput, Dropdown, Icon, SelectInput, TextInput, useI18n, useDebounceFn } from '@bagelink/vue'
5
- import { computed } from 'vue'
5
+ import { computed, ref, useAttrs } from 'vue'
6
6
 
7
7
  type OptionsSource = Option[] | ((query: string) => Promise<Option[]>)
8
8
 
@@ -25,13 +25,28 @@ const props = defineProps<{
25
25
 
26
26
  const emit = defineEmits<{
27
27
  change: [value: QueryConditions<T>]
28
+ save: [value: QueryConditions<T>]
28
29
  }>()
29
30
 
30
31
  const model = defineModel<QueryConditions<T>>({ default: () => [] })
31
32
 
33
+ // Internal working copy — may contain incomplete conditions for UI purposes
34
+ const internalModel = ref<QueryConditions<T>>([...model.value] as QueryConditions<T>)
35
+
32
36
  const { $t } = useI18n()
37
+ const attrs = useAttrs()
38
+ const hasSaveListener = computed(() => !!attrs.onSave)
39
+
40
+ function isComplete(c: { field: string, op: ComparisonOperator, value: any }) {
41
+ return c.field && c.op && (c.op === 'pr' || (c.value !== '' && c.value !== null && c.value !== undefined))
42
+ }
33
43
 
34
- const debouncedEmit = useDebounceFn((value: QueryConditions<T>) => { emit('change', value) }, 400)
44
+ const debouncedFlush = useDebounceFn(() => {
45
+ const complete = internalModel.value.filter(isComplete) as QueryConditions<T>
46
+ console.log('[Filter] flushing - internal:', internalModel.value, '| complete:', complete)
47
+ model.value = complete
48
+ emit('change', complete)
49
+ }, 400)
35
50
 
36
51
  let conditionIdCounter = 0
37
52
  function generateId() {
@@ -78,7 +93,7 @@ const currentTexts = computed(() => ({
78
93
  const conditionIds = new Map<number, string>()
79
94
 
80
95
  const conditions = computed(() => {
81
- const arr = model.value || []
96
+ const arr = internalModel.value || []
82
97
  return arr.map((cond, index) => {
83
98
  // Get or create stable ID for this index
84
99
  if (!conditionIds.has(index)) {
@@ -144,7 +159,7 @@ function parseValue(value: string | number | boolean | null): string | number |
144
159
  }
145
160
 
146
161
  function updateConditionAtIndex(index: number, updates: Partial<{ field: string, op: ComparisonOperator, value: string | number | boolean | null, connector: LogicalOperator }>) {
147
- const newModel = [...model.value]
162
+ const newModel = [...internalModel.value]
148
163
  const existing = newModel[index]
149
164
  if (!existing) return
150
165
 
@@ -155,9 +170,8 @@ function updateConditionAtIndex(index: number, updates: Partial<{ field: string,
155
170
  if (updates.connector !== undefined) updated.connector = updates.connector
156
171
 
157
172
  newModel[index] = updated
158
- model.value = newModel
159
- const completeConditions = newModel.filter(c => c.field && c.op && (c.op === 'pr' || (c.value !== '' && c.value !== null && c.value !== undefined)))
160
- debouncedEmit(completeConditions)
173
+ internalModel.value = newModel as QueryConditions<T>
174
+ debouncedFlush()
161
175
  }
162
176
 
163
177
  function addCondition() {
@@ -168,28 +182,28 @@ function addCondition() {
168
182
  value: '' as any,
169
183
  connector: model.value.length > 0 ? 'and' as LogicalOperator : undefined,
170
184
  }
171
- const newModel = [...model.value, newCondition]
172
- model.value = newModel
173
- // don't emit incomplete new condition
185
+ const newModel = [...internalModel.value, newCondition]
186
+ internalModel.value = newModel as QueryConditions<T>
187
+ console.log('[Filter] addCondition - skipping flush (incomplete)')
174
188
  }
175
189
 
176
190
  function removeCondition(index: number) {
177
- const newModel = [...model.value]
191
+ const newModel = [...internalModel.value]
178
192
  newModel.splice(index, 1)
179
- // Clear connector on new first item
180
193
  if (newModel.length > 0 && newModel[0].connector) {
181
194
  newModel[0] = { ...newModel[0], connector: undefined }
182
195
  }
183
- // Clean up ID mapping
184
196
  conditionIds.delete(index)
185
- model.value = newModel
186
- debouncedEmit(newModel)
197
+ internalModel.value = newModel as QueryConditions<T>
198
+ debouncedFlush()
187
199
  }
188
200
 
189
201
  function clearAll() {
190
202
  conditionIds.clear()
191
- model.value = []
192
- debouncedEmit([])
203
+ internalModel.value = [] as unknown as QueryConditions<T>
204
+ model.value = [] as unknown as QueryConditions<T>
205
+ console.log('[Filter] clearAll')
206
+ emit('change', [] as unknown as QueryConditions<T>)
193
207
  }
194
208
 
195
209
  function getFieldType(fieldValue: string): string {
@@ -248,9 +262,11 @@ function onConnectorChange(id: string, connector: LogicalOperator) {
248
262
  <TransitionGroup name="condition">
249
263
  <div
250
264
  v-for="(condition, index) in conditions" :key="condition.id"
251
- class="grid filter-row gap-025 align-items-center pt-025" :class="{
265
+ class="grid gap-025 align-items-center pt-025" :class="{
252
266
  'mt-025': index > 0 && condition.connector === 'or',
253
267
  'pt-075 border-top-or': index > 0 && condition.connector === 'or',
268
+ 'first-filter-row': index === 0,
269
+ 'filter-row': index > 0,
254
270
  }"
255
271
  >
256
272
  <!-- Connector (AND/OR) -->
@@ -263,7 +279,7 @@ function onConnectorChange(id: string, connector: LogicalOperator) {
263
279
  @update:model-value="(v: LogicalOperator) => onConnectorChange(condition.id, v)"
264
280
  />
265
281
  </div>
266
- <div v-else />
282
+ <!-- <div v-else /> -->
267
283
 
268
284
  <!-- Field selector -->
269
285
  <SelectInput
@@ -327,10 +343,16 @@ function onConnectorChange(id: string, connector: LogicalOperator) {
327
343
 
328
344
  <div class="flex gap-1 space-between">
329
345
  <Btn icon="add" flat thin :value="currentTexts.buttons.addCondition" @click="addCondition" />
330
- <Btn
331
- v-if="conditions.length > 0" icon="delete_sweep" flat thin color="gray"
332
- :value="currentTexts.buttons.clearAll" @click="clearAll"
333
- />
346
+ <div class="flex gap-05">
347
+ <Btn
348
+ v-if="conditions.length > 0" icon="delete_sweep" flat thin color="gray"
349
+ :value="currentTexts.buttons.clearAll" @click="clearAll"
350
+ />
351
+ <Btn
352
+ v-if="hasSaveListener" icon="save" thin color="primary" :value="$t('filter.buttons.save')"
353
+ @click="emit('save', internalModel.filter(isComplete))"
354
+ />
355
+ </div>
334
356
  </div>
335
357
  </div>
336
358
  </Dropdown>
@@ -350,6 +372,10 @@ function onConnectorChange(id: string, connector: LogicalOperator) {
350
372
  font-size: 12px !important;
351
373
  }
352
374
 
375
+ .first-filter-row {
376
+ grid-template-columns: minmax(90px, 0.5fr) minmax(170px, 0.75fr) minmax(120px, 0.5fr) auto;
377
+ }
378
+
353
379
  .filter-row {
354
380
  grid-template-columns: 50px minmax(90px, 0.5fr) minmax(170px, 0.75fr) minmax(120px, 0.5fr) auto;
355
381
  }
@@ -361,7 +361,7 @@ export function formatDate(
361
361
  let locale: Intl.LocalesArgument | undefined
362
362
  let timeZone: string | undefined
363
363
  let rest: Partial<Pick<Intl.DateTimeFormatOptions, 'hour12'>> = {}
364
-
364
+ console.log('formatOrOpts', formatOrOpts)
365
365
  // Handle both overloads
366
366
  if (typeof formatOrOpts === 'string') {
367
367
  // First overload: format string directly
@@ -375,6 +375,13 @@ export function formatDate(
375
375
  }
376
376
 
377
377
  if (!date) { return '' }
378
+
379
+ // Handle named format shortcuts before token replacement
380
+ if (format === 'ISO' || format === 'ISO8601') {
381
+ const d = typeof date === 'string' || typeof date === 'number' ? new Date(date) : date
382
+ return Number.isNaN(d.getTime()) ? '' : d.toISOString()
383
+ }
384
+
378
385
  format = format || 'DD.MM.YY'
379
386
 
380
387
  locale = locale || getActiveLocale()