@bagelink/vue 1.15.267 → 1.15.271
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/dist/components/FilterQuery.vue.d.ts.map +1 -1
- package/dist/components/dataTable/DataTable.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/index.vue.d.ts.map +1 -1
- package/dist/dialog/Dialog.vue.d.ts +1 -0
- package/dist/dialog/Dialog.vue.d.ts.map +1 -1
- package/dist/i18n/index.d.ts +42 -0
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/index.cjs +103 -76
- package/dist/index.mjs +10261 -9990
- package/dist/style.css +1 -1
- package/dist/utils/queryFilter.d.ts +13 -1
- package/dist/utils/queryFilter.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/FilterQuery.vue +123 -11
- package/src/components/dataTable/DataTable.vue +24 -5
- package/src/components/form/inputs/RichText/editor.css +28 -0
- package/src/components/form/inputs/RichText/index.vue +57 -5
- package/src/dialog/Dialog.vue +9 -9
- package/src/i18n/locales/en.json +9 -2
- package/src/i18n/locales/es.json +9 -2
- package/src/i18n/locales/fr.json +9 -2
- package/src/i18n/locales/he.json +9 -2
- package/src/i18n/locales/it.json +9 -2
- package/src/i18n/locales/ru.json +9 -2
- package/src/utils/queryFilter.ts +128 -11
package/src/i18n/locales/it.json
CHANGED
|
@@ -77,13 +77,17 @@
|
|
|
77
77
|
"ew": "Finisce con",
|
|
78
78
|
"pr": "Presente",
|
|
79
79
|
"in": "Nella lista",
|
|
80
|
-
"nin": "Non nella lista"
|
|
80
|
+
"nin": "Non nella lista",
|
|
81
|
+
"between": "Tra"
|
|
81
82
|
},
|
|
82
83
|
"placeholders": {
|
|
83
84
|
"selectField": "Seleziona campo",
|
|
84
85
|
"selectOption": "Seleziona opzione",
|
|
85
86
|
"selectDate": "Seleziona data",
|
|
86
|
-
"enterValue": "Valore"
|
|
87
|
+
"enterValue": "Valore",
|
|
88
|
+
"from": "Da",
|
|
89
|
+
"to": "A",
|
|
90
|
+
"commaSeparated": "Valori separati da virgole"
|
|
87
91
|
},
|
|
88
92
|
"buttons": {
|
|
89
93
|
"addCondition": "Aggiungi condizione",
|
|
@@ -270,5 +274,8 @@
|
|
|
270
274
|
"addToCalendar": {
|
|
271
275
|
"addTo": "Aggiungi a {name}",
|
|
272
276
|
"addToCalendar": "Aggiungi al calendario"
|
|
277
|
+
},
|
|
278
|
+
"guidedHelp": {
|
|
279
|
+
"hint": "La guida è sempre disponibile sul punto interrogativo."
|
|
273
280
|
}
|
|
274
281
|
}
|
package/src/i18n/locales/ru.json
CHANGED
|
@@ -77,13 +77,17 @@
|
|
|
77
77
|
"ew": "Заканчивается на",
|
|
78
78
|
"pr": "Присутствует",
|
|
79
79
|
"in": "В списке",
|
|
80
|
-
"nin": "Не в списке"
|
|
80
|
+
"nin": "Не в списке",
|
|
81
|
+
"between": "Между"
|
|
81
82
|
},
|
|
82
83
|
"placeholders": {
|
|
83
84
|
"selectField": "Выберите поле",
|
|
84
85
|
"selectOption": "Выберите вариант",
|
|
85
86
|
"selectDate": "Выберите дату",
|
|
86
|
-
"enterValue": "Значение"
|
|
87
|
+
"enterValue": "Значение",
|
|
88
|
+
"from": "От",
|
|
89
|
+
"to": "До",
|
|
90
|
+
"commaSeparated": "Значения через запятую"
|
|
87
91
|
},
|
|
88
92
|
"buttons": {
|
|
89
93
|
"addCondition": "Добавить условие",
|
|
@@ -270,5 +274,8 @@
|
|
|
270
274
|
"addToCalendar": {
|
|
271
275
|
"addTo": "Добавить в {name}",
|
|
272
276
|
"addToCalendar": "Добавить в календарь"
|
|
277
|
+
},
|
|
278
|
+
"guidedHelp": {
|
|
279
|
+
"hint": "Обучение всегда доступно по знаку вопроса."
|
|
273
280
|
}
|
|
274
281
|
}
|
package/src/utils/queryFilter.ts
CHANGED
|
@@ -43,8 +43,9 @@ export type ComparisonOperator
|
|
|
43
43
|
| 'sw' // starts with
|
|
44
44
|
| 'ew' // ends with
|
|
45
45
|
| 'pr' // present (has value)
|
|
46
|
-
| 'in' // in list —
|
|
47
|
-
| 'nin' // not in list —
|
|
46
|
+
| 'in' // in list — native: field in ["a","b"] (scalar membership OR array overlap)
|
|
47
|
+
| 'nin' // not in list — native: field nin ["a","b"]
|
|
48
|
+
| 'between' // inclusive range — field between [lo, hi] (numbers or dates)
|
|
48
49
|
|
|
49
50
|
/**
|
|
50
51
|
* SCIM 2.0 logical operators
|
|
@@ -79,6 +80,14 @@ function formatValue(value: Primitive): string {
|
|
|
79
80
|
return String(value)
|
|
80
81
|
}
|
|
81
82
|
|
|
83
|
+
/**
|
|
84
|
+
* Format a list of values into a SCIM bracket literal, e.g. ["a","b",3].
|
|
85
|
+
* Used by list-value operators (in / nin / between).
|
|
86
|
+
*/
|
|
87
|
+
function formatList(values: Primitive[]): string {
|
|
88
|
+
return `[${values.map(formatValue).join(', ')}]`
|
|
89
|
+
}
|
|
90
|
+
|
|
82
91
|
/**
|
|
83
92
|
* Build a SCIM 2.0 query string from conditions array
|
|
84
93
|
*
|
|
@@ -110,12 +119,15 @@ export function buildQuery<T extends Record<string, any>>(
|
|
|
110
119
|
if (op === 'pr') {
|
|
111
120
|
parts.push(`${field} pr`)
|
|
112
121
|
} else if (op === 'in' || op === 'nin') {
|
|
122
|
+
// Native list membership / array-overlap: field in ["a","b"].
|
|
113
123
|
const values = Array.isArray(value) ? value : (value != null ? [value] : [])
|
|
114
124
|
if (values.length === 0) continue
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
125
|
+
parts.push(`${field} ${op} ${formatList(values)}`)
|
|
126
|
+
} else if (op === 'between') {
|
|
127
|
+
// Inclusive range: field between [lo, hi]. Requires exactly two bounds.
|
|
128
|
+
const bounds = Array.isArray(value) ? value : []
|
|
129
|
+
if (bounds.length !== 2 || bounds[0] == null || bounds[1] == null) continue
|
|
130
|
+
parts.push(`${field} between ${formatList(bounds)}`)
|
|
119
131
|
} else {
|
|
120
132
|
parts.push(`${field} ${op} ${formatValue(value as Primitive ?? null)}`)
|
|
121
133
|
}
|
|
@@ -210,6 +222,30 @@ export class QueryFilter<T extends Record<string, any>> {
|
|
|
210
222
|
return this
|
|
211
223
|
}
|
|
212
224
|
|
|
225
|
+
/**
|
|
226
|
+
* In list — native membership / array overlap: field in ["a","b"]
|
|
227
|
+
*/
|
|
228
|
+
in<K extends DeepKeyOf<T>>(field: K, values: Primitive[]): this {
|
|
229
|
+
this.parts.push(`${field as string} in ${formatList(values)}`)
|
|
230
|
+
return this
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Not in list: field nin ["a","b"]
|
|
235
|
+
*/
|
|
236
|
+
nin<K extends DeepKeyOf<T>>(field: K, values: Primitive[]): this {
|
|
237
|
+
this.parts.push(`${field as string} nin ${formatList(values)}`)
|
|
238
|
+
return this
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Inclusive range: field between [lo, hi]
|
|
243
|
+
*/
|
|
244
|
+
between<K extends DeepKeyOf<T>>(field: K, lo: number | string, hi: number | string): this {
|
|
245
|
+
this.parts.push(`${field as string} between ${formatList([lo, hi])}`)
|
|
246
|
+
return this
|
|
247
|
+
}
|
|
248
|
+
|
|
213
249
|
/**
|
|
214
250
|
* AND logical operator
|
|
215
251
|
*/
|
|
@@ -361,8 +397,7 @@ export function range<T extends Record<string, any>>(
|
|
|
361
397
|
max: number | string
|
|
362
398
|
): string {
|
|
363
399
|
return buildQuery<T>([
|
|
364
|
-
{ field, op: '
|
|
365
|
-
{ field, op: 'le', value: max, connector: 'and' },
|
|
400
|
+
{ field, op: 'between', value: [min, max] },
|
|
366
401
|
])
|
|
367
402
|
}
|
|
368
403
|
|
|
@@ -418,6 +453,9 @@ export function evaluateQuery(query: string, data: Record<string, any>): boolean
|
|
|
418
453
|
case 'sw': match = value != null && String(fieldValue).startsWith(String(value)); break
|
|
419
454
|
case 'ew': match = value != null && String(fieldValue).endsWith(String(value)); break
|
|
420
455
|
case 'pr': match = fieldValue != null; break
|
|
456
|
+
case 'in': match = matchesIn(fieldValue, value); break
|
|
457
|
+
case 'nin': match = !matchesIn(fieldValue, value); break
|
|
458
|
+
case 'between': match = matchesBetween(fieldValue, value); break
|
|
421
459
|
default: break
|
|
422
460
|
}
|
|
423
461
|
|
|
@@ -440,8 +478,30 @@ function getNestedValue(obj: Record<string, any>, path: string): any {
|
|
|
440
478
|
return path.split('.').reduce<any>((acc, key) => acc?.[key], obj)
|
|
441
479
|
}
|
|
442
480
|
|
|
443
|
-
|
|
481
|
+
/** in — scalar membership OR array overlap (any shared element). */
|
|
482
|
+
function matchesIn(fieldValue: any, value: Primitive | Primitive[] | undefined): boolean {
|
|
483
|
+
const candidates = Array.isArray(value) ? value : (value != null ? [value] : [])
|
|
484
|
+
if (candidates.length === 0) return false
|
|
485
|
+
if (Array.isArray(fieldValue)) return fieldValue.some(v => candidates.includes(v))
|
|
486
|
+
return candidates.includes(fieldValue)
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/** between [lo, hi] — inclusive range (numbers or comparable strings/dates). */
|
|
490
|
+
function matchesBetween(fieldValue: any, value: Primitive | Primitive[] | undefined): boolean {
|
|
491
|
+
if (!Array.isArray(value) || value.length !== 2 || fieldValue == null) return false
|
|
492
|
+
const [lo, hi] = value
|
|
493
|
+
if (lo == null || hi == null) return false
|
|
494
|
+
const nLo = Number(lo); const nHi = Number(hi); const nVal = Number(fieldValue)
|
|
495
|
+
if (!Number.isNaN(nLo) && !Number.isNaN(nHi) && !Number.isNaN(nVal)) {
|
|
496
|
+
return nVal >= nLo && nVal <= nHi
|
|
497
|
+
}
|
|
498
|
+
return String(fieldValue) >= String(lo) && String(fieldValue) <= String(hi)
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
const OPERATORS: ComparisonOperator[] = ['eq', 'ne', 'gt', 'ge', 'lt', 'le', 'co', 'sw', 'ew', 'pr', 'in', 'nin', 'between']
|
|
444
502
|
const CONNECTORS: LogicalOperator[] = ['and', 'or']
|
|
503
|
+
/** Operators whose value is a bracket list literal. */
|
|
504
|
+
const LIST_OPERATORS: ComparisonOperator[] = ['in', 'nin', 'between']
|
|
445
505
|
|
|
446
506
|
/**
|
|
447
507
|
* Parse a value string into a Primitive
|
|
@@ -460,6 +520,37 @@ function parseValue(valueStr: string): Primitive {
|
|
|
460
520
|
return trimmed
|
|
461
521
|
}
|
|
462
522
|
|
|
523
|
+
/**
|
|
524
|
+
* Parse a bracket list literal token `["a", "b", 3]` into an array of Primitives.
|
|
525
|
+
* Splits on top-level commas (ignoring commas inside quoted items).
|
|
526
|
+
*/
|
|
527
|
+
function parseListLiteral(token: string): Primitive[] {
|
|
528
|
+
let inner = token.trim()
|
|
529
|
+
if (inner.startsWith('[')) inner = inner.slice(1)
|
|
530
|
+
if (inner.endsWith(']')) inner = inner.slice(0, -1)
|
|
531
|
+
if (inner.trim() === '') return []
|
|
532
|
+
|
|
533
|
+
const items: string[] = []
|
|
534
|
+
let current = ''
|
|
535
|
+
let inQuote = false
|
|
536
|
+
for (let i = 0; i < inner.length; i++) {
|
|
537
|
+
const ch = inner[i]
|
|
538
|
+
if (inQuote) {
|
|
539
|
+
if (ch === '\\' && inner[i + 1] === '"') { current += '\\"'; i++; continue }
|
|
540
|
+
if (ch === '"') { current += '"'; inQuote = false; continue }
|
|
541
|
+
current += ch
|
|
542
|
+
} else if (ch === '"') {
|
|
543
|
+
current += '"'; inQuote = true
|
|
544
|
+
} else if (ch === ',') {
|
|
545
|
+
items.push(current); current = ''
|
|
546
|
+
} else {
|
|
547
|
+
current += ch
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
if (current.trim() !== '') items.push(current)
|
|
551
|
+
return items.map(s => parseValue(s.trim()))
|
|
552
|
+
}
|
|
553
|
+
|
|
463
554
|
/**
|
|
464
555
|
* Parse a SCIM 2.0 query string into conditions array
|
|
465
556
|
* Supports grouping with parentheses: (a eq 1 or b eq 2) and c eq 3
|
|
@@ -551,12 +642,13 @@ function parseTokens<T extends Record<string, any>>(
|
|
|
551
642
|
throw new Error(`Invalid operator: ${op}`)
|
|
552
643
|
}
|
|
553
644
|
|
|
554
|
-
let value: Primitive | undefined
|
|
645
|
+
let value: Primitive | Primitive[] | undefined
|
|
555
646
|
if (op !== 'pr') {
|
|
556
647
|
if (i >= end) {
|
|
557
648
|
throw new Error(`Missing value for operator ${op}`)
|
|
558
649
|
}
|
|
559
|
-
|
|
650
|
+
const raw = tokens[i++]
|
|
651
|
+
value = LIST_OPERATORS.includes(op) ? parseListLiteral(raw) : parseValue(raw)
|
|
560
652
|
}
|
|
561
653
|
|
|
562
654
|
const condition: FilterCondition<T> = { field, op, value }
|
|
@@ -603,6 +695,31 @@ function tokenize(query: string): string[] {
|
|
|
603
695
|
i++
|
|
604
696
|
continue
|
|
605
697
|
}
|
|
698
|
+
// Handle a bracket list literal as a SINGLE token: [ ... ].
|
|
699
|
+
// Consume everything up to the matching ], respecting quotes so a
|
|
700
|
+
// quoted item containing ] doesn't terminate the list early.
|
|
701
|
+
if (char === '[') {
|
|
702
|
+
if (current) { tokens.push(current); current = '' }
|
|
703
|
+
let literal = '['
|
|
704
|
+
i++
|
|
705
|
+
let inStr = false
|
|
706
|
+
while (i < query.length) {
|
|
707
|
+
const c = query[i]
|
|
708
|
+
if (inStr) {
|
|
709
|
+
if (c === '\\' && query[i + 1] === '"') { literal += '\\"'; i += 2; continue }
|
|
710
|
+
if (c === '"') inStr = false
|
|
711
|
+
literal += c
|
|
712
|
+
i++
|
|
713
|
+
continue
|
|
714
|
+
}
|
|
715
|
+
if (c === '"') { inStr = true; literal += c; i++; continue }
|
|
716
|
+
literal += c
|
|
717
|
+
i++
|
|
718
|
+
if (c === ']') break
|
|
719
|
+
}
|
|
720
|
+
tokens.push(literal)
|
|
721
|
+
continue
|
|
722
|
+
}
|
|
606
723
|
// Handle parentheses as separate tokens
|
|
607
724
|
if (char === '(' || char === ')') {
|
|
608
725
|
if (current) {
|