@usssa/component-library 1.0.0-alpha.147 → 1.0.0-alpha.149
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/README.md +1 -1
- package/package.json +1 -1
- package/src/assets/no-result.svg +25 -0
- package/src/components/core/UBreadCrumbs.vue +121 -43
- package/src/components/core/UInputTextStd.vue +1 -0
- package/src/components/core/UInputTypeahead.vue +44 -0
- package/src/components/core/UInputTypeaheadAdvanceSearch.vue +85 -23
- package/src/components/core/UMenuDropdownAdvancedSearch.vue +7 -2
- package/src/components/core/UMenuSearch.vue +12 -774
- package/src/components/core/USelectStd.vue +23 -21
- package/src/components/core/USheet.vue +3 -2
- package/src/components/core/UToolbar/UCustomMenuIcon.vue +0 -2
- package/src/components/core/UTypeahead.vue +830 -0
- package/src/components/index.js +2 -0
- package/src/assets/no-result.png +0 -0
|
@@ -1,460 +1,37 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import UMenuDropdownAdvancedSearch from './UMenuDropdownAdvancedSearch.vue'
|
|
6
|
-
import UTabBtnStd from './UTabBtnStd.vue'
|
|
7
|
-
import UTooltip from './UTooltip.vue'
|
|
8
|
-
import { categorizeObjects, deepEqual, parseInitials } from '../../utils/data'
|
|
9
|
-
import { useNotify } from '../../composables/useNotify'
|
|
2
|
+
import { ref, watch } from 'vue'
|
|
3
|
+
|
|
4
|
+
const emit = defineEmits(['onMenuHide', 'onMenuShow'])
|
|
10
5
|
|
|
11
|
-
const emit = defineEmits([
|
|
12
|
-
'onInvitePerson',
|
|
13
|
-
'onItemActionClick',
|
|
14
|
-
'updateCountry',
|
|
15
|
-
'updateModelVal',
|
|
16
|
-
'updateTab',
|
|
17
|
-
])
|
|
18
|
-
const loading = defineModel('loading')
|
|
19
6
|
const props = defineProps({
|
|
20
|
-
// Label for button to select a record
|
|
21
|
-
actionButtonLabel: {
|
|
22
|
-
type: String,
|
|
23
|
-
},
|
|
24
|
-
actionButtonLoading: {
|
|
25
|
-
type: Boolean,
|
|
26
|
-
},
|
|
27
|
-
addedBtnIcon: {
|
|
28
|
-
type: String,
|
|
29
|
-
},
|
|
30
|
-
// Set default tab
|
|
31
|
-
advancedSearchSelectedTab: {
|
|
32
|
-
type: String,
|
|
33
|
-
},
|
|
34
|
-
algoliaIndex: {
|
|
35
|
-
type: Object,
|
|
36
|
-
},
|
|
37
|
-
alreadyAddedIds: {
|
|
38
|
-
type: Array,
|
|
39
|
-
},
|
|
40
|
-
// Set context for component for special handling
|
|
41
|
-
// context.action (e.g. addContact)
|
|
42
|
-
// context.data (e.g. array of existing contacts)
|
|
43
|
-
context: {
|
|
44
|
-
type: Array,
|
|
45
|
-
},
|
|
46
|
-
disabledButtonColor: {
|
|
47
|
-
type: String,
|
|
48
|
-
},
|
|
49
|
-
exceedLimitCount: {
|
|
50
|
-
type: Number,
|
|
51
|
-
default: 50,
|
|
52
|
-
},
|
|
53
|
-
fields: {
|
|
54
|
-
type: Array,
|
|
55
|
-
},
|
|
56
|
-
headerLabel: {
|
|
57
|
-
type: String,
|
|
58
|
-
default: "I'm looking for",
|
|
59
|
-
},
|
|
60
|
-
labelIcon: {
|
|
61
|
-
type: String,
|
|
62
|
-
},
|
|
63
7
|
menuClass: {
|
|
64
8
|
type: String,
|
|
65
9
|
},
|
|
66
|
-
model: {
|
|
67
|
-
type: Object,
|
|
68
|
-
},
|
|
69
|
-
options: {
|
|
70
|
-
type: Array,
|
|
71
|
-
},
|
|
72
|
-
recentSearches: {
|
|
73
|
-
type: Array,
|
|
74
|
-
},
|
|
75
|
-
recentSearchesLoading: {
|
|
76
|
-
type: Boolean,
|
|
77
|
-
},
|
|
78
10
|
searchText: {
|
|
79
11
|
type: String,
|
|
80
12
|
},
|
|
81
|
-
// Show/hide advanced search
|
|
82
|
-
showAdvancedSearch: {
|
|
83
|
-
type: Boolean,
|
|
84
|
-
default: true,
|
|
85
|
-
},
|
|
86
|
-
// Show/hide entity tabs in advanced search
|
|
87
|
-
showAdvancedSearchTabs: {
|
|
88
|
-
type: Boolean,
|
|
89
|
-
default: true,
|
|
90
|
-
},
|
|
91
|
-
showCustomMenu: {
|
|
92
|
-
type: Boolean,
|
|
93
|
-
default: false,
|
|
94
|
-
},
|
|
95
|
-
showDescriptionTooltip: {
|
|
96
|
-
type: Boolean,
|
|
97
|
-
},
|
|
98
|
-
showInviteBtn: {
|
|
99
|
-
type: Boolean,
|
|
100
|
-
default: false,
|
|
101
|
-
},
|
|
102
|
-
// Show/hide recent searches
|
|
103
|
-
showRecentSelected: {
|
|
104
|
-
type: Boolean,
|
|
105
|
-
default: true,
|
|
106
|
-
},
|
|
107
|
-
size: {
|
|
108
|
-
type: String,
|
|
109
|
-
default: 'md',
|
|
110
|
-
},
|
|
111
|
-
//Advance search title
|
|
112
|
-
title: {
|
|
113
|
-
type: String,
|
|
114
|
-
default: 'Advanced search',
|
|
115
|
-
},
|
|
116
|
-
toolTipDisabledButton: {
|
|
117
|
-
type: String,
|
|
118
|
-
},
|
|
119
13
|
})
|
|
120
14
|
|
|
121
|
-
const { notify } = useNotify()
|
|
122
|
-
|
|
123
|
-
const advancedSearchApplyFilter = ref(false)
|
|
124
|
-
const advancedSearchFilterDirty = ref(false)
|
|
125
|
-
const advancedSearchFilterModelDefault = ref({})
|
|
126
|
-
const advancedSearchSelectedTab = ref(props.advancedSearchSelectedTab ?? null)
|
|
127
|
-
const exceedLimit = ref(false)
|
|
128
15
|
const searchMenuRef = ref(null)
|
|
129
16
|
const searchMenuShowing = ref(false)
|
|
130
|
-
const searchResults = ref(null)
|
|
131
|
-
const selectedItem = ref({})
|
|
132
|
-
const toggle = ref(false)
|
|
133
|
-
|
|
134
|
-
const recentSearches = computed({
|
|
135
|
-
get() {
|
|
136
|
-
let arr = props.recentSearches
|
|
137
|
-
if (props.context) {
|
|
138
|
-
arr = specialContextHandler(arr)
|
|
139
|
-
}
|
|
140
|
-
return arr
|
|
141
|
-
},
|
|
142
|
-
set(value) {
|
|
143
|
-
return value
|
|
144
|
-
},
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
const convertDate = (inputDate) => {
|
|
148
|
-
const [month, day, year] = inputDate.split('/')
|
|
149
|
-
return `${year}-${month}-${day}`
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
const handleTabChange = (val) => {
|
|
153
|
-
if (advancedSearchSelectedTab.value === val) {
|
|
154
|
-
advancedSearchSelectedTab.value = null
|
|
155
|
-
} else {
|
|
156
|
-
advancedSearchSelectedTab.value = val
|
|
157
|
-
}
|
|
158
|
-
Object.assign(
|
|
159
|
-
props.model,
|
|
160
|
-
structuredClone(toRaw(advancedSearchFilterModelDefault.value))
|
|
161
|
-
)
|
|
162
|
-
emit('updateTab', advancedSearchSelectedTab.value)
|
|
163
|
-
search()
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
const onApplyAdvancedSearchFilter = () => {
|
|
167
|
-
advancedSearchApplyFilter.value = true
|
|
168
|
-
advancedSearchFilterDirty.value = false
|
|
169
|
-
|
|
170
|
-
search()
|
|
171
|
-
updateAdvanceSearchToggle()
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
const onClearAdvancedSearchFilter = () => {
|
|
175
|
-
Object.assign(
|
|
176
|
-
props.model,
|
|
177
|
-
structuredClone(toRaw(advancedSearchFilterModelDefault.value))
|
|
178
|
-
)
|
|
179
|
-
advancedSearchApplyFilter.value = false
|
|
180
|
-
advancedSearchFilterDirty.value = false
|
|
181
|
-
search()
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
const onInvitePerson = (item) => {
|
|
185
|
-
emit('onInvitePerson', item)
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
const onItemActionClick = (item, isRecentSearchAction) => {
|
|
189
|
-
selectedItem.value = item
|
|
190
|
-
return emit(
|
|
191
|
-
'onItemActionClick',
|
|
192
|
-
item,
|
|
193
|
-
isRecentSearchAction,
|
|
194
|
-
searchMenuRef.value
|
|
195
|
-
)
|
|
196
|
-
}
|
|
197
17
|
|
|
198
18
|
const onMenuHide = () => {
|
|
199
19
|
searchMenuShowing.value = false
|
|
20
|
+
emit('onMenuHide')
|
|
200
21
|
}
|
|
201
22
|
|
|
202
23
|
const onMenuShow = () => {
|
|
203
24
|
searchMenuShowing.value = true
|
|
25
|
+
emit('onMenuShow')
|
|
204
26
|
}
|
|
205
27
|
|
|
206
|
-
const search = async () => {
|
|
207
|
-
try {
|
|
208
|
-
if (props.searchText.length < 2) {
|
|
209
|
-
searchResults.value = null
|
|
210
|
-
return void 0
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
loading.value = true
|
|
214
|
-
const configPayload = {}
|
|
215
|
-
const selectedTab = advancedSearchSelectedTab.value
|
|
216
|
-
if (selectedTab) {
|
|
217
|
-
configPayload.facetFilters = [`collection:${selectedTab}`]
|
|
218
|
-
} else {
|
|
219
|
-
let advancedSearchTabOptions = props.options.map((option) => {
|
|
220
|
-
return `collection:${option.id}`
|
|
221
|
-
})
|
|
222
|
-
configPayload.facetFilters = [advancedSearchTabOptions]
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
if (advancedSearchApplyFilter.value) {
|
|
226
|
-
const filters = props.model
|
|
227
|
-
let algoliaFilter = ''
|
|
228
|
-
|
|
229
|
-
const phoneNumber = filters?.selectedCountry?.code + filters?.phoneNumber
|
|
230
|
-
|
|
231
|
-
Object.keys(filters).map((key, index) => {
|
|
232
|
-
let filterValue = filters[key]
|
|
233
|
-
|
|
234
|
-
if (key === 'phoneNumber' && filterValue) {
|
|
235
|
-
filterValue = phoneNumber
|
|
236
|
-
} else if (key === 'startDate' && filterValue) {
|
|
237
|
-
filterValue = convertDate(filters.startDate)
|
|
238
|
-
} else if (key === 'endDate' && filterValue) {
|
|
239
|
-
filterValue = convertDate(filters.endDate)
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
switch (key) {
|
|
243
|
-
case 'city':
|
|
244
|
-
if (selectedTab === 'events' || selectedTab === 'venues') {
|
|
245
|
-
key = 'city'
|
|
246
|
-
} else {
|
|
247
|
-
key = 'address.city'
|
|
248
|
-
}
|
|
249
|
-
break
|
|
250
|
-
case 'state':
|
|
251
|
-
if (selectedTab === 'events' || selectedTab === 'venues') {
|
|
252
|
-
key = 'state'
|
|
253
|
-
} else {
|
|
254
|
-
key = 'address.state'
|
|
255
|
-
}
|
|
256
|
-
break
|
|
257
|
-
case 'postalCode':
|
|
258
|
-
if (selectedTab === 'venues') {
|
|
259
|
-
key = 'postalCode'
|
|
260
|
-
} else {
|
|
261
|
-
key = 'address.postalCode'
|
|
262
|
-
}
|
|
263
|
-
break
|
|
264
|
-
case 'selectedCountry':
|
|
265
|
-
key = 'address.country'
|
|
266
|
-
break
|
|
267
|
-
case 'emailAddress':
|
|
268
|
-
key = 'email'
|
|
269
|
-
break
|
|
270
|
-
case 'teamName':
|
|
271
|
-
key = 'name'
|
|
272
|
-
break
|
|
273
|
-
case 'phoneNumber':
|
|
274
|
-
key = 'mobileNumber'
|
|
275
|
-
break
|
|
276
|
-
case 'venueName':
|
|
277
|
-
key = 'name'
|
|
278
|
-
break
|
|
279
|
-
case 'eventName':
|
|
280
|
-
key = 'name'
|
|
281
|
-
break
|
|
282
|
-
case 'startDate':
|
|
283
|
-
key = 'startsOn'
|
|
284
|
-
break
|
|
285
|
-
case 'endDate':
|
|
286
|
-
key = 'endsOn'
|
|
287
|
-
break
|
|
288
|
-
case 'venueAddress':
|
|
289
|
-
key = 'streetAddress'
|
|
290
|
-
break
|
|
291
|
-
default:
|
|
292
|
-
key = key
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
if (filterValue && filterValue.length) {
|
|
296
|
-
algoliaFilter.length
|
|
297
|
-
? (algoliaFilter += ` AND ${key}:${filterValue}`)
|
|
298
|
-
: (algoliaFilter += `${key}:"${filterValue}"`)
|
|
299
|
-
}
|
|
300
|
-
})
|
|
301
|
-
|
|
302
|
-
if (algoliaFilter.length) {
|
|
303
|
-
configPayload.filters = algoliaFilter
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
const res = await props.algoliaIndex.search(props.searchText, configPayload)
|
|
308
|
-
|
|
309
|
-
if (res.hits.length >= props.exceedLimitCount) {
|
|
310
|
-
exceedLimit.value = true
|
|
311
|
-
} else {
|
|
312
|
-
exceedLimit.value = false
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
let results = res.hits
|
|
316
|
-
|
|
317
|
-
if (props.context) {
|
|
318
|
-
results = specialContextHandler(results)
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
results = categorizeObjects(results, 'collection')
|
|
322
|
-
|
|
323
|
-
if (Object.keys(results).length) {
|
|
324
|
-
searchResults.value = results
|
|
325
|
-
} else {
|
|
326
|
-
searchResults.value = null
|
|
327
|
-
}
|
|
328
|
-
return void 0
|
|
329
|
-
} catch (error) {
|
|
330
|
-
notify({
|
|
331
|
-
type: 'accent',
|
|
332
|
-
label: 'Search broke',
|
|
333
|
-
position: 'top',
|
|
334
|
-
})
|
|
335
|
-
} finally {
|
|
336
|
-
loading.value = false
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
const specialContextHandler = (results) => {
|
|
341
|
-
// Mark result records that are already exits
|
|
342
|
-
results = results.map((result) => {
|
|
343
|
-
const isAlreadyAddedSearch = props.context.filter(
|
|
344
|
-
(data) =>
|
|
345
|
-
data.id === result.id ||
|
|
346
|
-
data.id === result.docId ||
|
|
347
|
-
result.id === data.docId
|
|
348
|
-
)
|
|
349
|
-
|
|
350
|
-
isAlreadyAddedSearch.every((data) => {
|
|
351
|
-
if (
|
|
352
|
-
data.id === result.id ||
|
|
353
|
-
data.id === result.docId ||
|
|
354
|
-
result.id === data.docId
|
|
355
|
-
) {
|
|
356
|
-
if (data?.tooltip) {
|
|
357
|
-
result.disableTooltip = data?.tooltip
|
|
358
|
-
}
|
|
359
|
-
if (data?.label) {
|
|
360
|
-
result.label = data?.label
|
|
361
|
-
}
|
|
362
|
-
result.color = data?.color ?? props.disabledButtonColor
|
|
363
|
-
}
|
|
364
|
-
})
|
|
365
|
-
|
|
366
|
-
if (isAlreadyAddedSearch && isAlreadyAddedSearch.length > 0) {
|
|
367
|
-
return {
|
|
368
|
-
...result,
|
|
369
|
-
disable: true,
|
|
370
|
-
btnProps: {
|
|
371
|
-
...result.btnProps,
|
|
372
|
-
color: result.btnProps?.color ?? result?.color,
|
|
373
|
-
},
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
if (props.alreadyAddedIds?.length) {
|
|
377
|
-
if (props.alreadyAddedIds.includes(result.docId || result.id)) {
|
|
378
|
-
return {
|
|
379
|
-
...result,
|
|
380
|
-
disable: true,
|
|
381
|
-
label: 'Added',
|
|
382
|
-
icon: props.addedBtnIcon,
|
|
383
|
-
btnProps: {
|
|
384
|
-
...result.btnProps,
|
|
385
|
-
color: result.btnProps?.color ?? 'positive',
|
|
386
|
-
outline: false,
|
|
387
|
-
},
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
return {
|
|
392
|
-
...result,
|
|
393
|
-
}
|
|
394
|
-
})
|
|
395
|
-
|
|
396
|
-
return results
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
const transformCategory = (category) => {
|
|
400
|
-
switch (category) {
|
|
401
|
-
case 'users':
|
|
402
|
-
return 'People'
|
|
403
|
-
case 'teams':
|
|
404
|
-
return 'Teams'
|
|
405
|
-
case 'events':
|
|
406
|
-
return 'Events'
|
|
407
|
-
case 'venues':
|
|
408
|
-
return 'Venues'
|
|
409
|
-
default:
|
|
410
|
-
return 'Other'
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
const updateAdvanceSearchToggle = (val) => {
|
|
415
|
-
toggle.value = !toggle.value
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
const updateCountry = (val, label) => {
|
|
419
|
-
emit('updateCountry', val, label)
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
const updateModelVal = (event, label) => {
|
|
423
|
-
emit('updateModelVal', event, label)
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
//Assign default model value on tab change
|
|
427
|
-
watch(
|
|
428
|
-
() => props.model,
|
|
429
|
-
(value) => {
|
|
430
|
-
advancedSearchFilterModelDefault.value = Object.assign(
|
|
431
|
-
{},
|
|
432
|
-
structuredClone(toRaw(value))
|
|
433
|
-
)
|
|
434
|
-
},
|
|
435
|
-
{ immediate: true }
|
|
436
|
-
)
|
|
437
|
-
|
|
438
|
-
watch(
|
|
439
|
-
() => props.model,
|
|
440
|
-
(newValue) => {
|
|
441
|
-
if (deepEqual(newValue, advancedSearchFilterModelDefault.value)) {
|
|
442
|
-
advancedSearchFilterDirty.value = false
|
|
443
|
-
} else {
|
|
444
|
-
advancedSearchFilterDirty.value = true
|
|
445
|
-
}
|
|
446
|
-
},
|
|
447
|
-
{ deep: true }
|
|
448
|
-
)
|
|
449
|
-
|
|
450
28
|
watch(
|
|
451
29
|
() => props.searchText,
|
|
452
30
|
(value) => {
|
|
453
31
|
if (value.length >= 2) {
|
|
454
|
-
if (!searchMenuShowing.value)
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
searchResults.value = null
|
|
32
|
+
if (!searchMenuShowing.value) {
|
|
33
|
+
searchMenuRef.value.show()
|
|
34
|
+
}
|
|
458
35
|
}
|
|
459
36
|
}
|
|
460
37
|
)
|
|
@@ -464,7 +41,7 @@ watch(
|
|
|
464
41
|
<q-menu
|
|
465
42
|
v-bind="$attrs"
|
|
466
43
|
v-model="searchMenuShowing"
|
|
467
|
-
:class="`u-search-option-menu ${menuClass}`"
|
|
44
|
+
:class="[`u-search-option-menu ${menuClass}`]"
|
|
468
45
|
aria-label="search menu"
|
|
469
46
|
fit
|
|
470
47
|
no-focus
|
|
@@ -475,304 +52,7 @@ watch(
|
|
|
475
52
|
@hide="onMenuHide"
|
|
476
53
|
@show="onMenuShow"
|
|
477
54
|
>
|
|
478
|
-
<
|
|
479
|
-
:class="`u-typeahead-menu q-pl-ba q-pt-ba size-${size}`"
|
|
480
|
-
role="menuitem"
|
|
481
|
-
>
|
|
482
|
-
<div v-if="showAdvancedSearchTabs" class="q-pb-xs">
|
|
483
|
-
<span class="text-overline-xs">{{ headerLabel }}</span>
|
|
484
|
-
|
|
485
|
-
<!-- Tab options -->
|
|
486
|
-
|
|
487
|
-
<div class="tabs-option">
|
|
488
|
-
<UTabBtnStd
|
|
489
|
-
:buttonTabsOptions="options"
|
|
490
|
-
:modelValue="advancedSearchSelectedTab"
|
|
491
|
-
size="sm"
|
|
492
|
-
:standard="false"
|
|
493
|
-
@onTabClick="handleTabChange"
|
|
494
|
-
/>
|
|
495
|
-
</div>
|
|
496
|
-
</div>
|
|
497
|
-
<div class="q-mt-xs q-mr-ba">
|
|
498
|
-
<!-- Menu dropdown -->
|
|
499
|
-
<UMenuDropdownAdvancedSearch
|
|
500
|
-
v-if="showAdvancedSearch"
|
|
501
|
-
:disbaleApplyFilter="!advancedSearchFilterDirty"
|
|
502
|
-
:fields="fields"
|
|
503
|
-
:labelIcon="labelIcon"
|
|
504
|
-
:model="model"
|
|
505
|
-
:showCustomMenu="showCustomMenu"
|
|
506
|
-
:size="size"
|
|
507
|
-
:title="title"
|
|
508
|
-
:toggle="toggle"
|
|
509
|
-
@onApplyAdvancedSearchFilter="onApplyAdvancedSearchFilter"
|
|
510
|
-
@onClearAdvancedSearchFilter="onClearAdvancedSearchFilter"
|
|
511
|
-
@updateAdvanceSearchToggle="(val) => updateAdvanceSearchToggle(val)"
|
|
512
|
-
@updateCountry="(event, label) => updateCountry(event, label)"
|
|
513
|
-
@updateModelVal="(event, label) => updateModelVal(event, label)"
|
|
514
|
-
>
|
|
515
|
-
</UMenuDropdownAdvancedSearch>
|
|
516
|
-
|
|
517
|
-
<!-- Search Result list -->
|
|
518
|
-
|
|
519
|
-
<q-list
|
|
520
|
-
v-if="searchResults && !exceedLimit && searchText.length"
|
|
521
|
-
class="search-list q-mt-xs q-px-xxs"
|
|
522
|
-
>
|
|
523
|
-
<span class="text-overline-xs">Search results</span>
|
|
524
|
-
<template
|
|
525
|
-
v-for="category of Object.keys(searchResults)"
|
|
526
|
-
:key="category"
|
|
527
|
-
>
|
|
528
|
-
<q-item-label caption>
|
|
529
|
-
<span class="text-caption-sm q-py-xxs">
|
|
530
|
-
{{ transformCategory(category) }}
|
|
531
|
-
</span>
|
|
532
|
-
</q-item-label>
|
|
533
|
-
<q-item
|
|
534
|
-
v-for="item of searchResults[category]"
|
|
535
|
-
class="q-pa-xs list-item"
|
|
536
|
-
clickable
|
|
537
|
-
:key="item.id"
|
|
538
|
-
>
|
|
539
|
-
<q-item-section side>
|
|
540
|
-
<UAvatar
|
|
541
|
-
v-if="
|
|
542
|
-
!item.profilePictureUrl ||
|
|
543
|
-
item.profilePictureUrl?.nullValue === 0
|
|
544
|
-
"
|
|
545
|
-
:aria-label="item.name"
|
|
546
|
-
:name="parseInitials(item.name)"
|
|
547
|
-
size="md"
|
|
548
|
-
/>
|
|
549
|
-
<UAvatar
|
|
550
|
-
v-else
|
|
551
|
-
:aria-label="item.name"
|
|
552
|
-
:image="item.profilePictureUrl"
|
|
553
|
-
:name="item.name"
|
|
554
|
-
:round="true"
|
|
555
|
-
:showIndicator="false"
|
|
556
|
-
size="md"
|
|
557
|
-
/>
|
|
558
|
-
</q-item-section>
|
|
559
|
-
|
|
560
|
-
<q-item-section>
|
|
561
|
-
<q-item-label class="text-caption-md wrapped-text">
|
|
562
|
-
{{ item?.name }}
|
|
563
|
-
</q-item-label>
|
|
564
|
-
<q-item-label class="text-body-xs text-neutral-9 wrapped-text">
|
|
565
|
-
{{ item?.description }}
|
|
566
|
-
</q-item-label>
|
|
567
|
-
|
|
568
|
-
<UTooltip
|
|
569
|
-
v-if="showDescriptionTooltip"
|
|
570
|
-
class="description-tooltip"
|
|
571
|
-
anchor="top middle"
|
|
572
|
-
:description="item.description"
|
|
573
|
-
self="bottom middle"
|
|
574
|
-
/>
|
|
575
|
-
</q-item-section>
|
|
576
|
-
|
|
577
|
-
<q-item-section side>
|
|
578
|
-
<UBtnStd
|
|
579
|
-
v-bind="item.btnProps"
|
|
580
|
-
:color="item.btnProps?.color ?? 'primary'"
|
|
581
|
-
:disable="
|
|
582
|
-
item.disable ||
|
|
583
|
-
(selectedItem?.id !== item.id && actionButtonLoading)
|
|
584
|
-
"
|
|
585
|
-
:leftIcon="item.icon"
|
|
586
|
-
:label="item.label ? item.label : actionButtonLabel"
|
|
587
|
-
:loading="
|
|
588
|
-
selectedItem?.id === item.id ? actionButtonLoading : false
|
|
589
|
-
"
|
|
590
|
-
:outline="item.btnProps?.outline ?? true"
|
|
591
|
-
size="sm"
|
|
592
|
-
@click.stop="onItemActionClick(item)"
|
|
593
|
-
>
|
|
594
|
-
<template
|
|
595
|
-
v-if="
|
|
596
|
-
(item.disableTooltip && item.disable) ||
|
|
597
|
-
(item.disable && toolTipDisabledButton)
|
|
598
|
-
"
|
|
599
|
-
#tooltip
|
|
600
|
-
>
|
|
601
|
-
<UTooltip
|
|
602
|
-
anchor="top middle"
|
|
603
|
-
:description="
|
|
604
|
-
item.disableTooltip
|
|
605
|
-
? item.disableTooltip
|
|
606
|
-
: toolTipDisabledButton
|
|
607
|
-
"
|
|
608
|
-
:offset="[0, 4]"
|
|
609
|
-
self="bottom middle"
|
|
610
|
-
/>
|
|
611
|
-
</template>
|
|
612
|
-
</UBtnStd>
|
|
613
|
-
</q-item-section>
|
|
614
|
-
</q-item>
|
|
615
|
-
</template>
|
|
616
|
-
</q-list>
|
|
617
|
-
|
|
618
|
-
<!-- No data section -->
|
|
619
|
-
|
|
620
|
-
<div
|
|
621
|
-
v-if="searchText.length && !searchResults && !exceedLimit && !loading"
|
|
622
|
-
>
|
|
623
|
-
<div class="items-center column q-py-ba">
|
|
624
|
-
<img
|
|
625
|
-
alt="No result found"
|
|
626
|
-
aria-label="No result found"
|
|
627
|
-
src="../../assets/no-result.png"
|
|
628
|
-
/>
|
|
629
|
-
<span class="text-caption-lg">No results found</span>
|
|
630
|
-
<span class="text-body-sm text-neutral-9 q-mt-xxs q-mb-ba">
|
|
631
|
-
Invite user to join USSSA.
|
|
632
|
-
</span>
|
|
633
|
-
</div>
|
|
634
|
-
|
|
635
|
-
<div v-if="showInviteBtn" class="row items-center full-width">
|
|
636
|
-
<span
|
|
637
|
-
:class="`searchText-${size} text-caption-md q-mr-xs col wrapped-text`"
|
|
638
|
-
>
|
|
639
|
-
{{ searchText }}
|
|
640
|
-
</span>
|
|
641
|
-
<UBtnStd
|
|
642
|
-
color="primary"
|
|
643
|
-
label="Invite"
|
|
644
|
-
outline
|
|
645
|
-
size="sm"
|
|
646
|
-
@click.stop="onInvitePerson(item, false)"
|
|
647
|
-
/>
|
|
648
|
-
</div>
|
|
649
|
-
</div>
|
|
650
|
-
|
|
651
|
-
<!-- Exceed limit section -->
|
|
652
|
-
|
|
653
|
-
<div v-if="searchText.length && exceedLimit && searchResults">
|
|
654
|
-
<div class="column q-my-ba items-center">
|
|
655
|
-
<img
|
|
656
|
-
alt="No result found"
|
|
657
|
-
aria-label="No result found"
|
|
658
|
-
src="../../assets/no-result.png"
|
|
659
|
-
/>
|
|
660
|
-
<span class="text-caption-lg">Results exceeds limit.</span>
|
|
661
|
-
<span class="text-body-sm text-neutral-9 q-mt-xxs text-center">
|
|
662
|
-
Please select advanced search to provide more details for your
|
|
663
|
-
search.
|
|
664
|
-
</span>
|
|
665
|
-
</div>
|
|
666
|
-
</div>
|
|
667
|
-
|
|
668
|
-
<!-- Recently selected list -->
|
|
669
|
-
|
|
670
|
-
<q-list class="search-list q-mt-xs q-px-xxs">
|
|
671
|
-
<div
|
|
672
|
-
v-if="showRecentSelected && recentSearchesLoading"
|
|
673
|
-
class="row justify-between items-center"
|
|
674
|
-
>
|
|
675
|
-
<span class="text-overline-xs"> Recently Selected </span>
|
|
676
|
-
|
|
677
|
-
<q-spinner
|
|
678
|
-
v-if="recentSearchesLoading"
|
|
679
|
-
color="grey-14"
|
|
680
|
-
size="1rem"
|
|
681
|
-
/>
|
|
682
|
-
</div>
|
|
683
|
-
<div
|
|
684
|
-
v-if="
|
|
685
|
-
showRecentSelected &&
|
|
686
|
-
recentSearches &&
|
|
687
|
-
recentSearches.length &&
|
|
688
|
-
!recentSearchesLoading
|
|
689
|
-
"
|
|
690
|
-
>
|
|
691
|
-
<span class="text-overline-xs"> Recently Selected </span>
|
|
692
|
-
|
|
693
|
-
<template v-for="item in recentSearches" :key="item.id">
|
|
694
|
-
<q-item class="list-item" clickable>
|
|
695
|
-
<q-item-section side>
|
|
696
|
-
<UAvatar
|
|
697
|
-
v-if="
|
|
698
|
-
!item.profilePictureUrl ||
|
|
699
|
-
item.profilePictureUrl?.nullValue === 0
|
|
700
|
-
"
|
|
701
|
-
:aria-label="item.name"
|
|
702
|
-
:name="parseInitials(item.name)"
|
|
703
|
-
size="md"
|
|
704
|
-
/>
|
|
705
|
-
<UAvatar
|
|
706
|
-
v-else
|
|
707
|
-
:aria-label="item.name"
|
|
708
|
-
:image="item.profilePictureUrl"
|
|
709
|
-
:round="true"
|
|
710
|
-
:showIndicator="false"
|
|
711
|
-
size="md"
|
|
712
|
-
/>
|
|
713
|
-
</q-item-section>
|
|
714
|
-
|
|
715
|
-
<q-item-section>
|
|
716
|
-
<q-item-label class="text-caption-md wrapped-text">
|
|
717
|
-
{{ item?.name }}
|
|
718
|
-
</q-item-label>
|
|
719
|
-
<q-item-label
|
|
720
|
-
class="text-body-xs text-neutral-9 label wrapped-text"
|
|
721
|
-
>
|
|
722
|
-
{{ item?.description }}
|
|
723
|
-
</q-item-label>
|
|
724
|
-
<UTooltip
|
|
725
|
-
v-if="showDescriptionTooltip"
|
|
726
|
-
class="description-tooltip"
|
|
727
|
-
anchor="top middle"
|
|
728
|
-
:description="item.description"
|
|
729
|
-
self="bottom middle"
|
|
730
|
-
/>
|
|
731
|
-
</q-item-section>
|
|
732
|
-
|
|
733
|
-
<q-item-section side>
|
|
734
|
-
<UBtnStd
|
|
735
|
-
v-bind="item.btnProps"
|
|
736
|
-
:color="item.btnProps?.color ?? 'primary'"
|
|
737
|
-
:disable="
|
|
738
|
-
item.disable ||
|
|
739
|
-
(selectedItem?.id !== item.id && actionButtonLoading)
|
|
740
|
-
"
|
|
741
|
-
:leftIcon="item.icon"
|
|
742
|
-
:label="item.label ? item.label : actionButtonLabel"
|
|
743
|
-
:loading="
|
|
744
|
-
selectedItem?.id === item.id ? actionButtonLoading : false
|
|
745
|
-
"
|
|
746
|
-
:outline="item.btnProps?.outline ?? true"
|
|
747
|
-
size="sm"
|
|
748
|
-
@click.stop="onItemActionClick(item, true)"
|
|
749
|
-
>
|
|
750
|
-
<template
|
|
751
|
-
v-if="
|
|
752
|
-
(item.disableTooltip && item.disable) ||
|
|
753
|
-
(item.disable && toolTipDisabledButton)
|
|
754
|
-
"
|
|
755
|
-
#tooltip
|
|
756
|
-
>
|
|
757
|
-
<UTooltip
|
|
758
|
-
anchor="top middle"
|
|
759
|
-
:description="
|
|
760
|
-
item.disableTooltip
|
|
761
|
-
? item.disableTooltip
|
|
762
|
-
: toolTipDisabledButton
|
|
763
|
-
"
|
|
764
|
-
:offset="[0, 4]"
|
|
765
|
-
self="bottom middle"
|
|
766
|
-
/>
|
|
767
|
-
</template>
|
|
768
|
-
</UBtnStd>
|
|
769
|
-
</q-item-section>
|
|
770
|
-
</q-item>
|
|
771
|
-
</template>
|
|
772
|
-
</div>
|
|
773
|
-
</q-list>
|
|
774
|
-
</div>
|
|
775
|
-
</q-list>
|
|
55
|
+
<slot name="menuContent" :menuRef="searchMenuRef" />
|
|
776
56
|
</q-menu>
|
|
777
57
|
</template>
|
|
778
58
|
|
|
@@ -784,48 +64,6 @@ watch(
|
|
|
784
64
|
padding-bottom: $ba
|
|
785
65
|
max-height: 20rem
|
|
786
66
|
box-shadow: 0px 8px 8px 0px rgba(16, 17, 20, 0.16)
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
overflow-wrap: unset
|
|
790
|
-
.u-tabs-outer .u-tab-sm
|
|
791
|
-
margin: 0 $xxs
|
|
792
|
-
padding: 0 $ba
|
|
793
|
-
.u-tabs-outer .u-tab-sm:first-child
|
|
794
|
-
margin-left: 0px
|
|
795
|
-
.u-tabs-outer .u-tab-sm:last-child
|
|
796
|
-
margin-right: 0px
|
|
797
|
-
.u-tabs-outer .q-tab__content .q-icon
|
|
798
|
-
font-size: 0.75rem
|
|
799
|
-
.tabs-option
|
|
800
|
-
display: flex
|
|
801
|
-
overflow-y: auto
|
|
802
|
-
scrollbar-width: none
|
|
803
|
-
flex-direction: column
|
|
804
|
-
align-items: flex-start
|
|
805
|
-
border-radius: $xs
|
|
806
|
-
background: $neutral-1
|
|
807
|
-
&.size-sm
|
|
808
|
-
max-width: 25.5625rem
|
|
809
|
-
&.size-md
|
|
810
|
-
max-width: 26.5rem
|
|
811
|
-
.search-list
|
|
812
|
-
display: flex
|
|
813
|
-
flex-direction: column
|
|
814
|
-
gap: $xxs
|
|
815
|
-
.list-item
|
|
816
|
-
border-radius: $xs
|
|
817
|
-
align-items: center
|
|
818
|
-
display: flex
|
|
819
|
-
cursor: default !important
|
|
820
|
-
gap: $xs
|
|
821
|
-
.q-item__section--avatar
|
|
822
|
-
min-width: 0px
|
|
823
|
-
.q-item__section--side
|
|
824
|
-
padding: 0px
|
|
825
|
-
.wrapped-text
|
|
826
|
-
white-space: normal
|
|
827
|
-
overflow: hidden
|
|
828
|
-
word-wrap: break-word
|
|
829
|
-
.description-tooltip
|
|
830
|
-
transform: translateX(20px)
|
|
67
|
+
right: $ba
|
|
68
|
+
width: 25.5rem
|
|
831
69
|
</style>
|