@bagelink/vue 1.8.7 → 1.8.12
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/Filter.vue.d.ts +5 -4
- package/dist/components/Filter.vue.d.ts.map +1 -1
- package/dist/index.cjs +23 -23
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +4411 -4328
- package/dist/style.css +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/queryFilter.d.ts +12 -8
- package/dist/utils/queryFilter.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/Filter.vue +124 -112
- package/src/index.ts +2 -1
- package/src/utils/index.ts +1 -1
- package/src/utils/queryFilter.ts +30 -22
package/dist/utils/index.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ export * as bagelFormUtils from './BagelFormUtils';
|
|
|
26
26
|
export { useForm } from './BagelFormUtils';
|
|
27
27
|
export { useLang } from './lang';
|
|
28
28
|
export type { ComparisonOperator, FilterCondition, LogicalOperator, QueryConditions, QueryFilter } from './queryFilter';
|
|
29
|
-
export { anyOf, parseQuery,
|
|
29
|
+
export { anyOf, parseQuery, queryFilter, range, search } from './queryFilter';
|
|
30
30
|
export { formatString } from './strings';
|
|
31
31
|
export declare function pathKeyToURL(pathKey?: string): string | undefined;
|
|
32
32
|
export declare function getNestedValue(obj: any, path?: string, defaultValue?: any): any;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AAI1E,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,IAAI,GAAE,MAAY,QAO1D;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,UAMlC;AAED,wBAAgB,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQ3D;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,iBAGtE;AAED,wBAAgB,QAAQ,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,UAG3C;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,IAAI,QAIrE;AAED,wBAAgB,QAAQ,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,UAOpE;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,EAC7C,KAAK,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,EACxB,QAAQ,CAAC,EAAE,GAAG,EACd,GAAG,CAAC,EAAE,CAAC;;EAwBP;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,OAO9C;AAED,wBAAgB,SAAS,CAAC,QAAQ,CAAC,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,EAAE,OAAO,CAAC,EAAE,MAAM,OAG5E;AAED,eAAO,MAAM,MAAM,GAAI,YAAY,GAAG,YAA0C,CAAA;AAEhF,wBAAgB,iBAAiB,CAAC,CAAC,EAClC,IAAI,CAAC,EAAE,GAAG,EAAE,EACZ,OAAO,CAAC,EAAE,MAAM,EAAE,GAChB,cAAc,CAAC,CAAC,CAAC,CAgBnB;AAED,wBAAgB,KAAK,CAAC,EAAE,GAAE,MAAY,oBAErC;AAKD,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA2CxF;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAatD;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,UAIvC;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,EAAE,aAAa,SAAO,GAAG,MAAM,GAAG,SAAS,CAG/G;AAED,OAAO,KAAK,cAAc,MAAM,kBAAkB,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAE1C,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AAEhC,YAAY,EAAE,kBAAkB,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AACvH,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -57,7 +57,7 @@ export type QueryConditions<T extends Record<string, any> = Record<string, any>>
|
|
|
57
57
|
* // → 'name eq "John" and age gt 18'
|
|
58
58
|
* ```
|
|
59
59
|
*/
|
|
60
|
-
export declare function buildQuery<T extends Record<string, any>>(conditions
|
|
60
|
+
export declare function buildQuery<T extends Record<string, any>>(conditions?: QueryConditions<T>): string;
|
|
61
61
|
/**
|
|
62
62
|
* Query Builder for SCIM 2.0 filtering
|
|
63
63
|
*/
|
|
@@ -145,22 +145,26 @@ export declare class QueryFilter<T extends Record<string, any>> {
|
|
|
145
145
|
private formatValue;
|
|
146
146
|
}
|
|
147
147
|
/**
|
|
148
|
-
* Build a query string from conditions
|
|
148
|
+
* Build a query string from conditions or create a chainable query builder
|
|
149
149
|
*
|
|
150
150
|
* @example
|
|
151
151
|
* ```typescript
|
|
152
152
|
* // From conditions array
|
|
153
|
-
*
|
|
153
|
+
* queryFilter<Person>([
|
|
154
154
|
* { field: 'first_name', op: 'eq', value: 'John' },
|
|
155
155
|
* { field: 'age', op: 'gt', value: 18, connector: 'and' },
|
|
156
|
-
* ])
|
|
156
|
+
* ]).build()
|
|
157
|
+
* // → 'first_name eq "John" and age gt 18'
|
|
158
|
+
*
|
|
159
|
+
* // Chainable builder
|
|
160
|
+
* queryFilter<Person>().eq('first_name', 'John').and().gt('age', 18).build()
|
|
157
161
|
* // → 'first_name eq "John" and age gt 18'
|
|
158
162
|
*
|
|
159
|
-
* // Empty returns empty
|
|
160
|
-
*
|
|
163
|
+
* // Empty returns empty builder
|
|
164
|
+
* queryFilter() // → QueryFilter instance
|
|
161
165
|
* ```
|
|
162
166
|
*/
|
|
163
|
-
export declare function
|
|
167
|
+
export declare function queryFilter<T extends Record<string, any>>(conditions?: QueryConditions<T>): QueryFilter<T>;
|
|
164
168
|
/**
|
|
165
169
|
* Create a query that checks if any of the fields match the value
|
|
166
170
|
*/
|
|
@@ -188,6 +192,6 @@ export declare function search<T extends Record<string, any>>(fields: Array<Deep
|
|
|
188
192
|
* // → [{ field: 'email', op: 'pr' }]
|
|
189
193
|
* ```
|
|
190
194
|
*/
|
|
191
|
-
export declare function parseQuery<T extends Record<string, any> = Record<string, any>>(queryString
|
|
195
|
+
export declare function parseQuery<T extends Record<string, any> = Record<string, any>>(queryString?: string): QueryConditions<T>;
|
|
192
196
|
export {};
|
|
193
197
|
//# sourceMappingURL=queryFilter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queryFilter.d.ts","sourceRoot":"","sources":["../../src/utils/queryFilter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,KAAK,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAA;AAEjD,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,SAAS,GACpC,KAAK,GACL;KACA,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;CACtD,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAA;AAEpB;;GAEG;AACH,MAAM,MAAM,kBAAkB,
|
|
1
|
+
{"version":3,"file":"queryFilter.d.ts","sourceRoot":"","sources":["../../src/utils/queryFilter.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,25 +1,18 @@
|
|
|
1
1
|
<script setup lang="ts" generic="T extends Record<string, any>">
|
|
2
2
|
import type { Option } from '@bagelink/vue'
|
|
3
|
-
import type { ComparisonOperator } from '
|
|
3
|
+
import type { ComparisonOperator, LogicalOperator, QueryConditions } from './queryFilter'
|
|
4
4
|
import { Btn, DateInput, Dropdown, Icon, SelectInput, TextInput } from '@bagelink/vue'
|
|
5
5
|
import { computed } from 'vue'
|
|
6
6
|
|
|
7
7
|
type OptionsSource = Option[] | ((query: string) => Promise<Option[]>)
|
|
8
8
|
type Language = 'he' | 'en'
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
type QueryObject<T = Record<string, any>> = Record<string, any> & T
|
|
12
|
-
interface Condition {
|
|
13
|
-
pr?: boolean
|
|
14
|
-
[operator: string]: any
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
interface FilterCondition {
|
|
10
|
+
interface UICondition {
|
|
18
11
|
id: string
|
|
19
12
|
field: string
|
|
20
13
|
operator: ComparisonOperator
|
|
21
14
|
value: string
|
|
22
|
-
connector:
|
|
15
|
+
connector: LogicalOperator | ''
|
|
23
16
|
}
|
|
24
17
|
|
|
25
18
|
const props = defineProps<{
|
|
@@ -33,10 +26,15 @@ const props = defineProps<{
|
|
|
33
26
|
}>()
|
|
34
27
|
|
|
35
28
|
const emit = defineEmits<{
|
|
36
|
-
change: [value:
|
|
29
|
+
change: [value: QueryConditions<T>]
|
|
37
30
|
}>()
|
|
38
31
|
|
|
39
|
-
const model = defineModel<
|
|
32
|
+
const model = defineModel<QueryConditions<T>>({ default: () => [] })
|
|
33
|
+
|
|
34
|
+
let conditionIdCounter = 0
|
|
35
|
+
function generateId() {
|
|
36
|
+
return `cond_${++conditionIdCounter}_${Date.now()}`
|
|
37
|
+
}
|
|
40
38
|
|
|
41
39
|
// Localization data
|
|
42
40
|
const texts = {
|
|
@@ -113,45 +111,27 @@ const texts = {
|
|
|
113
111
|
// Get current language texts
|
|
114
112
|
const currentTexts = computed(() => texts[props.language || 'en'])
|
|
115
113
|
|
|
116
|
-
//
|
|
117
|
-
const
|
|
118
|
-
const obj = model.value
|
|
119
|
-
if (Object.keys(obj).filter(k => !k.startsWith('_')).length === 0) {
|
|
120
|
-
return [] as FilterCondition[]
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const result: FilterCondition[] = []
|
|
124
|
-
const useOr = (obj as any)._or === true
|
|
125
|
-
|
|
126
|
-
for (const [field, value] of Object.entries(obj)) {
|
|
127
|
-
if (field.startsWith('_')) continue
|
|
114
|
+
// Map model conditions to UI conditions with stable IDs
|
|
115
|
+
const conditionIds = new Map<number, string>()
|
|
128
116
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
117
|
+
const conditions = computed(() => {
|
|
118
|
+
const arr = model.value || []
|
|
119
|
+
return arr.map((cond, index) => {
|
|
120
|
+
// Get or create stable ID for this index
|
|
121
|
+
if (!conditionIds.has(index)) {
|
|
122
|
+
conditionIds.set(index, generateId())
|
|
135
123
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const val = (cond as any)[op]
|
|
145
|
-
condition.value = val === null ? 'null' : String(val)
|
|
146
|
-
}
|
|
147
|
-
} else if (value !== undefined) {
|
|
148
|
-
condition.value = value === null ? 'null' : String(value)
|
|
124
|
+
const id = conditionIds.get(index)!
|
|
125
|
+
|
|
126
|
+
const uiCond: UICondition = {
|
|
127
|
+
id,
|
|
128
|
+
field: cond.field as string,
|
|
129
|
+
operator: cond.op,
|
|
130
|
+
value: cond.value === null ? 'null' : cond.value === undefined ? '' : String(cond.value),
|
|
131
|
+
connector: index > 0 ? (cond.connector || 'and') : '',
|
|
149
132
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
return result
|
|
133
|
+
return uiCond
|
|
134
|
+
})
|
|
155
135
|
})
|
|
156
136
|
|
|
157
137
|
const allOperatorOptions = computed(() => [
|
|
@@ -191,43 +171,60 @@ const booleanOptions = computed(() => [
|
|
|
191
171
|
{ label: currentTexts.value.boolean.false, value: 'false' },
|
|
192
172
|
])
|
|
193
173
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
} else if (operator === 'pr') {
|
|
207
|
-
(newModel as any)[field] = { pr: true }
|
|
208
|
-
} else {
|
|
209
|
-
(newModel as any)[field] = { [operator]: parsedValue }
|
|
210
|
-
}
|
|
174
|
+
function parseValue(value: string): string | number | boolean | null {
|
|
175
|
+
if (value === 'true') return true
|
|
176
|
+
if (value === 'false') return false
|
|
177
|
+
if (value === 'null') return null
|
|
178
|
+
if (!Number.isNaN(Number(value)) && value.trim() !== '') return Number(value)
|
|
179
|
+
return value
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function updateConditionAtIndex(index: number, updates: Partial<{ field: string, op: ComparisonOperator, value: string, connector: LogicalOperator }>) {
|
|
183
|
+
const newModel = [...model.value]
|
|
184
|
+
const existing = newModel[index]
|
|
185
|
+
if (!existing) return
|
|
211
186
|
|
|
187
|
+
const updated = { ...existing }
|
|
188
|
+
if (updates.field !== undefined) updated.field = updates.field
|
|
189
|
+
if (updates.op !== undefined) updated.op = updates.op
|
|
190
|
+
if (updates.value !== undefined) updated.value = parseValue(updates.value)
|
|
191
|
+
if (updates.connector !== undefined) updated.connector = updates.connector
|
|
192
|
+
|
|
193
|
+
newModel[index] = updated
|
|
212
194
|
model.value = newModel
|
|
213
195
|
emit('change', newModel)
|
|
214
196
|
}
|
|
215
197
|
|
|
216
198
|
function addCondition() {
|
|
217
|
-
const field = props.fields[0]?.value || '
|
|
218
|
-
|
|
199
|
+
const field = props.fields[0]?.value || 'field'
|
|
200
|
+
const newCondition = {
|
|
201
|
+
field,
|
|
202
|
+
op: 'eq' as ComparisonOperator,
|
|
203
|
+
value: '' as any,
|
|
204
|
+
connector: model.value.length > 0 ? 'and' as LogicalOperator : undefined,
|
|
205
|
+
}
|
|
206
|
+
const newModel = [...model.value, newCondition]
|
|
207
|
+
model.value = newModel
|
|
208
|
+
emit('change', newModel)
|
|
219
209
|
}
|
|
220
210
|
|
|
221
|
-
function removeCondition(
|
|
222
|
-
const newModel =
|
|
223
|
-
|
|
211
|
+
function removeCondition(index: number) {
|
|
212
|
+
const newModel = [...model.value]
|
|
213
|
+
newModel.splice(index, 1)
|
|
214
|
+
// Clear connector on new first item
|
|
215
|
+
if (newModel.length > 0 && newModel[0].connector) {
|
|
216
|
+
newModel[0] = { ...newModel[0], connector: undefined }
|
|
217
|
+
}
|
|
218
|
+
// Clean up ID mapping
|
|
219
|
+
conditionIds.delete(index)
|
|
224
220
|
model.value = newModel
|
|
225
221
|
emit('change', newModel)
|
|
226
222
|
}
|
|
227
223
|
|
|
228
224
|
function clearAll() {
|
|
229
|
-
|
|
230
|
-
|
|
225
|
+
conditionIds.clear()
|
|
226
|
+
model.value = []
|
|
227
|
+
emit('change', [])
|
|
231
228
|
}
|
|
232
229
|
|
|
233
230
|
function getFieldType(fieldValue: string): string {
|
|
@@ -242,35 +239,28 @@ const activeFiltersCount = computed(() => {
|
|
|
242
239
|
return conditions.value.filter(c => Boolean(c.field) && (c.operator === 'pr' || Boolean(c.value))).length
|
|
243
240
|
})
|
|
244
241
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
Reflect.deleteProperty(newModel, oldField)
|
|
249
|
-
|
|
250
|
-
let parsedValue: any = condition.value
|
|
251
|
-
if (condition.value === 'true') parsedValue = true
|
|
252
|
-
else if (condition.value === 'false') parsedValue = false
|
|
253
|
-
else if (condition.value === 'null') parsedValue = null
|
|
254
|
-
else if (!Number.isNaN(Number(condition.value)) && condition.value.trim() !== '') parsedValue = Number(condition.value)
|
|
255
|
-
|
|
256
|
-
if (condition.operator === 'eq') {
|
|
257
|
-
(newModel as any)[newField] = parsedValue
|
|
258
|
-
} else if (condition.operator === 'pr') {
|
|
259
|
-
(newModel as any)[newField] = { pr: true }
|
|
260
|
-
} else {
|
|
261
|
-
(newModel as any)[newField] = { [condition.operator]: parsedValue }
|
|
262
|
-
}
|
|
242
|
+
function getConditionIndex(id: string): number {
|
|
243
|
+
return conditions.value.findIndex(c => c.id === id)
|
|
244
|
+
}
|
|
263
245
|
|
|
264
|
-
|
|
265
|
-
|
|
246
|
+
function onFieldChange(id: string, newField: string) {
|
|
247
|
+
const index = getConditionIndex(id)
|
|
248
|
+
if (index >= 0) updateConditionAtIndex(index, { field: newField })
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function onOperatorChange(id: string, operator: ComparisonOperator) {
|
|
252
|
+
const index = getConditionIndex(id)
|
|
253
|
+
if (index >= 0) updateConditionAtIndex(index, { op: operator })
|
|
266
254
|
}
|
|
267
255
|
|
|
268
|
-
function
|
|
269
|
-
|
|
256
|
+
function onValueChange(id: string, value: string) {
|
|
257
|
+
const index = getConditionIndex(id)
|
|
258
|
+
if (index >= 0) updateConditionAtIndex(index, { value })
|
|
270
259
|
}
|
|
271
260
|
|
|
272
|
-
function
|
|
273
|
-
|
|
261
|
+
function onConnectorChange(id: string, connector: LogicalOperator) {
|
|
262
|
+
const index = getConditionIndex(id)
|
|
263
|
+
if (index >= 0) updateConditionAtIndex(index, { connector })
|
|
274
264
|
}
|
|
275
265
|
</script>
|
|
276
266
|
|
|
@@ -293,21 +283,31 @@ function onValueChange(field: string, operator: ComparisonOperator, value: strin
|
|
|
293
283
|
<TransitionGroup name="condition">
|
|
294
284
|
<div
|
|
295
285
|
v-for="(condition, index) in conditions" :key="condition.id"
|
|
296
|
-
class="grid filter-row gap-025 align-items-center
|
|
286
|
+
class="grid filter-row gap-025 align-items-center pt-025"
|
|
287
|
+
:class="{
|
|
288
|
+
'mt-025': index > 0 && condition.connector === 'or',
|
|
289
|
+
'pt-075 border-top-or': index > 0 && condition.connector === 'or',
|
|
290
|
+
}"
|
|
297
291
|
>
|
|
298
|
-
<!-- Connector (AND/OR)
|
|
299
|
-
<div v-if="index > 0" class="min-w-
|
|
300
|
-
<
|
|
301
|
-
|
|
302
|
-
|
|
292
|
+
<!-- Connector (AND/OR) -->
|
|
293
|
+
<div v-if="index > 0" class="min-w-60px">
|
|
294
|
+
<SelectInput
|
|
295
|
+
:model-value="condition.connector || 'and'"
|
|
296
|
+
:options="[
|
|
297
|
+
{ label: currentTexts.connectors.and, value: 'and' },
|
|
298
|
+
{ label: currentTexts.connectors.or, value: 'or' },
|
|
299
|
+
]"
|
|
300
|
+
class="m-0 and-or-select txt-12"
|
|
301
|
+
@update:model-value="(v: LogicalOperator) => onConnectorChange(condition.id, v)"
|
|
302
|
+
/>
|
|
303
303
|
</div>
|
|
304
|
-
<div v-else class="
|
|
304
|
+
<div v-else class="" />
|
|
305
305
|
|
|
306
306
|
<!-- Field selector -->
|
|
307
307
|
<SelectInput
|
|
308
308
|
:model-value="condition.field" :options="fields"
|
|
309
309
|
:placeholder="currentTexts.placeholders.selectField" class="m-0 light-input borderHover"
|
|
310
|
-
@update:model-value="(v: string) => onFieldChange(condition.
|
|
310
|
+
@update:model-value="(v: string) => onFieldChange(condition.id, v)"
|
|
311
311
|
/>
|
|
312
312
|
|
|
313
313
|
<!-- Operator selector -->
|
|
@@ -315,7 +315,7 @@ function onValueChange(field: string, operator: ComparisonOperator, value: strin
|
|
|
315
315
|
:model-value="condition.operator"
|
|
316
316
|
:options="getOperatorsForType(getFieldType(condition.field), !!getFieldOptions(condition.field))"
|
|
317
317
|
class="m-0 light-input borderHover"
|
|
318
|
-
@update:model-value="(v: ComparisonOperator) => onOperatorChange(condition.
|
|
318
|
+
@update:model-value="(v: ComparisonOperator) => onOperatorChange(condition.id, v)"
|
|
319
319
|
/>
|
|
320
320
|
|
|
321
321
|
<!-- Value input - type-specific -->
|
|
@@ -325,31 +325,31 @@ function onValueChange(field: string, operator: ComparisonOperator, value: strin
|
|
|
325
325
|
:options="getFieldOptions(condition.field)!"
|
|
326
326
|
:placeholder="currentTexts.placeholders.selectOption"
|
|
327
327
|
class="m-0 light-input borderHover" searchable
|
|
328
|
-
@update:model-value="(v: string) => onValueChange(condition.
|
|
328
|
+
@update:model-value="(v: string) => onValueChange(condition.id, v)"
|
|
329
329
|
/>
|
|
330
330
|
<SelectInput
|
|
331
331
|
v-else-if="getFieldType(condition.field) === 'boolean'"
|
|
332
332
|
:model-value="condition.value" :options="booleanOptions"
|
|
333
333
|
:placeholder="currentTexts.placeholders.selectOption"
|
|
334
334
|
class="m-0 light-input borderHover"
|
|
335
|
-
@update:model-value="(v: string) => onValueChange(condition.
|
|
335
|
+
@update:model-value="(v: string) => onValueChange(condition.id, v)"
|
|
336
336
|
/>
|
|
337
337
|
<DateInput
|
|
338
338
|
v-else-if="getFieldType(condition.field) === 'date'"
|
|
339
339
|
:model-value="condition.value" :placeholder="currentTexts.placeholders.selectDate"
|
|
340
340
|
class="m-0 light-input borderHover"
|
|
341
|
-
@update:model-value="(v: any) => onValueChange(condition.
|
|
341
|
+
@update:model-value="(v: any) => onValueChange(condition.id, String(v))"
|
|
342
342
|
/>
|
|
343
343
|
<TextInput
|
|
344
344
|
v-else-if="getFieldType(condition.field) === 'number'"
|
|
345
345
|
:model-value="condition.value" placeholder="0" type="number"
|
|
346
346
|
class="m-0 light-input borderHover"
|
|
347
|
-
@update:model-value="(v: string) => onValueChange(condition.
|
|
347
|
+
@update:model-value="(v: string) => onValueChange(condition.id, v)"
|
|
348
348
|
/>
|
|
349
349
|
<TextInput
|
|
350
350
|
v-else :model-value="condition.value"
|
|
351
351
|
:placeholder="currentTexts.placeholders.enterValue" class="m-0 light-input borderHover"
|
|
352
|
-
@update:model-value="(v: string) => onValueChange(condition.
|
|
352
|
+
@update:model-value="(v: string) => onValueChange(condition.id, v)"
|
|
353
353
|
/>
|
|
354
354
|
</template>
|
|
355
355
|
<div v-else />
|
|
@@ -357,7 +357,7 @@ function onValueChange(field: string, operator: ComparisonOperator, value: strin
|
|
|
357
357
|
<!-- Remove button -->
|
|
358
358
|
<Btn
|
|
359
359
|
icon="close" thin flat size="small" class="m_bg-gray-40 m_px-3 m_mx-auto"
|
|
360
|
-
@click="removeCondition(
|
|
360
|
+
@click="removeCondition(index)"
|
|
361
361
|
/>
|
|
362
362
|
</div>
|
|
363
363
|
</TransitionGroup>
|
|
@@ -375,8 +375,20 @@ function onValueChange(field: string, operator: ComparisonOperator, value: strin
|
|
|
375
375
|
</template>
|
|
376
376
|
|
|
377
377
|
<style scoped>
|
|
378
|
+
.and-or-select {
|
|
379
|
+
--input-font-size: 12px !important;
|
|
380
|
+
--input-background-color: transparent !important;
|
|
381
|
+
}
|
|
382
|
+
.and-or-select .selectinput-btn {
|
|
383
|
+
border: none;
|
|
384
|
+
width: 100%;
|
|
385
|
+
box-shadow: none;
|
|
386
|
+
padding: 0.25rem !important;
|
|
387
|
+
font-size: 12px !important;
|
|
388
|
+
}
|
|
389
|
+
|
|
378
390
|
.filter-row {
|
|
379
|
-
grid-template-columns:
|
|
391
|
+
grid-template-columns: 50px minmax(90px, 0.5fr) minmax(170px, 0.75fr) minmax(120px, 0.5fr) auto;
|
|
380
392
|
}
|
|
381
393
|
|
|
382
394
|
/* Transition animations */
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import './styles/bagel.css'
|
|
2
|
+
|
|
1
3
|
export * from './components'
|
|
2
4
|
export * from './components/form/useBagelFormState'
|
|
3
5
|
export * from './composables'
|
|
@@ -14,7 +16,6 @@ export * from './types'
|
|
|
14
16
|
export * from './utils'
|
|
15
17
|
export * from './utils/allCountries'
|
|
16
18
|
export * from './utils/BagelFormUtils'
|
|
17
|
-
import './styles/bagel.css'
|
|
18
19
|
|
|
19
20
|
export * from './utils/calendar/dateUtils'
|
|
20
21
|
export * from './utils/constants'
|
package/src/utils/index.ts
CHANGED
|
@@ -204,7 +204,7 @@ export { useForm } from './BagelFormUtils'
|
|
|
204
204
|
export { useLang } from './lang'
|
|
205
205
|
|
|
206
206
|
export type { ComparisonOperator, FilterCondition, LogicalOperator, QueryConditions, QueryFilter } from './queryFilter'
|
|
207
|
-
export { anyOf, parseQuery,
|
|
207
|
+
export { anyOf, parseQuery, queryFilter, range, search } from './queryFilter'
|
|
208
208
|
export { formatString } from './strings'
|
|
209
209
|
|
|
210
210
|
const URL_REGEX = /^https?:\/\/|^\/\//
|
package/src/utils/queryFilter.ts
CHANGED
|
@@ -32,17 +32,17 @@ type DeepKeyOf<T> = T extends Primitive
|
|
|
32
32
|
/**
|
|
33
33
|
* SCIM 2.0 comparison operators
|
|
34
34
|
*/
|
|
35
|
-
export type ComparisonOperator
|
|
36
|
-
| 'eq' // equal
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
35
|
+
export type ComparisonOperator
|
|
36
|
+
= | 'eq' // equal
|
|
37
|
+
| 'ne' // not equal
|
|
38
|
+
| 'gt' // greater than
|
|
39
|
+
| 'ge' // greater than or equal
|
|
40
|
+
| 'lt' // less than
|
|
41
|
+
| 'le' // less than or equal
|
|
42
|
+
| 'co' // contains
|
|
43
|
+
| 'sw' // starts with
|
|
44
|
+
| 'ew' // ends with
|
|
45
|
+
| 'pr' // present (has value)
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
48
|
* SCIM 2.0 logical operators
|
|
@@ -90,7 +90,7 @@ function formatValue(value: Primitive): string {
|
|
|
90
90
|
* ```
|
|
91
91
|
*/
|
|
92
92
|
export function buildQuery<T extends Record<string, any>>(
|
|
93
|
-
conditions
|
|
93
|
+
conditions?: QueryConditions<T>
|
|
94
94
|
): string {
|
|
95
95
|
if (!conditions || conditions.length === 0) return ''
|
|
96
96
|
|
|
@@ -298,25 +298,33 @@ export class QueryFilter<T extends Record<string, any>> {
|
|
|
298
298
|
}
|
|
299
299
|
|
|
300
300
|
/**
|
|
301
|
-
* Build a query string from conditions
|
|
301
|
+
* Build a query string from conditions or create a chainable query builder
|
|
302
302
|
*
|
|
303
303
|
* @example
|
|
304
304
|
* ```typescript
|
|
305
305
|
* // From conditions array
|
|
306
|
-
*
|
|
306
|
+
* queryFilter<Person>([
|
|
307
307
|
* { field: 'first_name', op: 'eq', value: 'John' },
|
|
308
308
|
* { field: 'age', op: 'gt', value: 18, connector: 'and' },
|
|
309
|
-
* ])
|
|
309
|
+
* ]).build()
|
|
310
|
+
* // → 'first_name eq "John" and age gt 18'
|
|
311
|
+
*
|
|
312
|
+
* // Chainable builder
|
|
313
|
+
* queryFilter<Person>().eq('first_name', 'John').and().gt('age', 18).build()
|
|
310
314
|
* // → 'first_name eq "John" and age gt 18'
|
|
311
315
|
*
|
|
312
|
-
* // Empty returns empty
|
|
313
|
-
*
|
|
316
|
+
* // Empty returns empty builder
|
|
317
|
+
* queryFilter() // → QueryFilter instance
|
|
314
318
|
* ```
|
|
315
319
|
*/
|
|
316
|
-
export function
|
|
317
|
-
conditions
|
|
318
|
-
):
|
|
319
|
-
|
|
320
|
+
export function queryFilter<T extends Record<string, any>>(
|
|
321
|
+
conditions?: QueryConditions<T>
|
|
322
|
+
): QueryFilter<T> {
|
|
323
|
+
const builder = new QueryFilter<T>()
|
|
324
|
+
if (conditions && conditions.length > 0) {
|
|
325
|
+
builder.raw(buildQuery(conditions))
|
|
326
|
+
}
|
|
327
|
+
return builder
|
|
320
328
|
}
|
|
321
329
|
|
|
322
330
|
/**
|
|
@@ -401,7 +409,7 @@ function parseValue(valueStr: string): Primitive {
|
|
|
401
409
|
* ```
|
|
402
410
|
*/
|
|
403
411
|
export function parseQuery<T extends Record<string, any> = Record<string, any>>(
|
|
404
|
-
queryString
|
|
412
|
+
queryString?: string
|
|
405
413
|
): QueryConditions<T> {
|
|
406
414
|
if (!queryString || !queryString.trim()) return []
|
|
407
415
|
|