@usssa/component-library 1.0.0-alpha.91 → 1.0.0-alpha.92

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usssa/component-library",
3
- "version": "1.0.0-alpha.91",
3
+ "version": "1.0.0-alpha.92",
4
4
  "description": "A Quasar component library project",
5
5
  "productName": "Quasar component library App",
6
6
  "author": "Troy Moreland <troy.moreland@usssa.com>",
@@ -1,12 +1,12 @@
1
1
  <script setup>
2
2
  import { computed, ref, toRaw, watch } from 'vue'
3
- import { Notify, SessionStorage } from 'quasar'
4
3
  import UAvatar from './UAvatar.vue'
5
4
  import UBtnStd from './UBtnStd.vue'
6
5
  import UInputTypeaheadAdvanceSearch from './UInputTypeaheadAdvanceSearch.vue'
7
6
  import UMenuDropdownAdvancedSearch from './UMenuDropdownAdvancedSearch.vue'
8
7
  import UTabBtnStd from './UTabBtnStd.vue'
9
8
  import UTooltip from './UTooltip.vue'
9
+ import { useNotify } from '../../composables/useNotify'
10
10
  import { parseInitials, categorizeObjects, deepEqual } from '../../utils/data'
11
11
 
12
12
  const props = defineProps({
@@ -21,11 +21,21 @@ const props = defineProps({
21
21
  advancedSearchSelectedTab: {
22
22
  type: String,
23
23
  },
24
+ actionButtonLoading: {
25
+ type: Boolean,
26
+ },
24
27
  // Set context for component for special handling
25
28
  // context.action (e.g. addContact)
26
29
  // context.data (e.g. array of existing contacts)
27
30
  context: {
28
- type: Object,
31
+ type: Array,
32
+ },
33
+ disabledButtonColor: {
34
+ type: String,
35
+ },
36
+ exceedLimitCount: {
37
+ type: Number,
38
+ default: 50,
29
39
  },
30
40
  fields: {
31
41
  type: Array,
@@ -38,11 +48,6 @@ const props = defineProps({
38
48
  type: String,
39
49
  default: 'fa-kit-duotone fa-filter-search',
40
50
  },
41
- //Number of maximum search result to show
42
- maxSearchResults: {
43
- type: Number,
44
- default: 5,
45
- },
46
51
  menuClass: {
47
52
  type: String,
48
53
  },
@@ -52,6 +57,12 @@ const props = defineProps({
52
57
  options: {
53
58
  type: Array,
54
59
  },
60
+ recentSearches: {
61
+ type: Array,
62
+ },
63
+ recentSearchesLoading: {
64
+ type: Boolean,
65
+ },
55
66
  showCustomMenu: {
56
67
  type: Boolean,
57
68
  default: false,
@@ -87,6 +98,9 @@ const props = defineProps({
87
98
  type: String,
88
99
  default: 'Advanced search',
89
100
  },
101
+ toolTipDisabledButton: {
102
+ type: String,
103
+ },
90
104
  })
91
105
 
92
106
  const emit = defineEmits([
@@ -98,6 +112,7 @@ const emit = defineEmits([
98
112
  ])
99
113
 
100
114
  const loading = defineModel('loading')
115
+ const { notify } = useNotify()
101
116
 
102
117
  const advancedSearchPendingFilterModel = structuredClone(toRaw(props.model))
103
118
  const advancedSearchSelectedTab = ref(props.advancedSearchSelectedTab ?? null)
@@ -113,11 +128,11 @@ const searchMenuShowing = ref(false)
113
128
 
114
129
  const recentSearches = computed({
115
130
  get() {
116
- let arr = SessionStorage.getItem('recentSearches') ?? []
117
- if (props.context && props.context.action) {
131
+ let arr = props.recentSearches
132
+ if (props.context) {
118
133
  arr = specialContextHandler(arr)
119
134
  }
120
- return arr.sort((a, b) => b.added_to_recent - a.added_to_recent)
135
+ return arr
121
136
  },
122
137
  set(value) {
123
138
  return value
@@ -173,50 +188,33 @@ const handleTabChange = (val) => {
173
188
  search()
174
189
  }
175
190
 
176
- const recentSearchHandler = (item) => {
177
- let index = recentSearches.value.findIndex((s) => s.id === item.id)
178
- if (index >= 0) {
179
- recentSearches.value.splice(index, 1)
180
- }
181
-
182
- if (recentSearches.value.length === props.maxSearchResults) {
183
- recentSearches.value.pop()
184
- }
185
-
186
- recentSearches.value.push({
187
- ...item,
188
- added_to_recent: new Date().valueOf(),
189
- })
190
-
191
- recentSearches.value.sort((a, b) => b.added_to_recent - a.added_to_recent)
192
-
193
- SessionStorage.set('recentSearches', recentSearches.value)
194
- }
195
-
196
191
  const onItemActionClick = (item) => {
197
- recentSearchHandler(item)
198
192
  return emit('onItemActionClick', item, searchMenuRef.value)
199
193
  }
200
194
 
201
195
  const specialContextHandler = (results) => {
202
- switch (props.context.action) {
203
- case 'addContact':
204
- // Mark result records that are already contacts
205
- results = results.map((result) => {
206
- const isAlreadyContactSearch = props.context.data.filter(
207
- (contact) => contact.userId === result.id
208
- )
209
- if (isAlreadyContactSearch && isAlreadyContactSearch.length > 0) {
210
- return {
211
- ...result,
212
- disable: true,
213
- tooltip: 'Person is already a contact',
214
- }
215
- }
216
- return result
217
- })
218
- return results
219
- }
196
+ // Mark result records that are already exits
197
+ results = results.map((result) => {
198
+ const isAlreadyContactSearch = props.context.filter(
199
+ (contact) => contact.id === result.id
200
+ )
201
+
202
+ if (isAlreadyContactSearch && isAlreadyContactSearch.length > 0) {
203
+ const tooltip = props.toolTipDisabledButton
204
+ const color = props.disabledButtonColor
205
+ return {
206
+ ...result,
207
+ disable: true,
208
+ btnProps: {
209
+ color,
210
+ },
211
+ tooltip,
212
+ }
213
+ }
214
+ return result
215
+ })
216
+
217
+ return results
220
218
  }
221
219
 
222
220
  const convertDate = (inputDate) => {
@@ -327,7 +325,7 @@ const search = async () => {
327
325
 
328
326
  const res = await props.algoliaIndex.search(props.searchText, configPayload)
329
327
 
330
- if (res.hits.length >= 50) {
328
+ if (res.hits.length >= props.exceedLimitCount) {
331
329
  exceedLimit.value = true
332
330
  } else {
333
331
  exceedLimit.value = false
@@ -335,7 +333,7 @@ const search = async () => {
335
333
 
336
334
  let results = res.hits
337
335
 
338
- if (props.context && data.context.action) {
336
+ if (props.context) {
339
337
  results = specialContextHandler(results)
340
338
  }
341
339
 
@@ -348,9 +346,10 @@ const search = async () => {
348
346
  }
349
347
  return void 0
350
348
  } catch (error) {
351
- Notify.create({
352
- type: 'error',
353
- message: 'Search broke',
349
+ notify({
350
+ type: 'accent',
351
+ label: 'Search broke',
352
+ position: 'top',
354
353
  })
355
354
  } finally {
356
355
  loading.value = false
@@ -527,6 +526,7 @@ watch(
527
526
  :color="item.btnProps?.color ?? 'primary'"
528
527
  :disable="item.disable"
529
528
  :label="actionButtonLabel"
529
+ :loading="actionButtonLoading"
530
530
  outline
531
531
  size="sm"
532
532
  @click.stop="onItemActionClick(item)"
@@ -596,56 +596,81 @@ watch(
596
596
 
597
597
  <!-- Recently selected list -->
598
598
 
599
- <q-list
600
- v-if="showRecentSelected && recentSearches.length"
601
- class="search-list q-mt-xs"
602
- >
603
- <span class="text-overline-xs">Recently Selected</span>
604
- <template v-for="item in recentSearches" :key="item.id">
605
- <q-item class="list-item" clickable>
606
- <q-item-section side>
607
- <UAvatar
608
- v-if="
609
- !item.profilePictureUrl ||
610
- item.profilePictureUrl?.nullValue === 0
611
- "
612
- :aria-label="item.name"
613
- :name="parseInitials(item.name)"
614
- size="md"
615
- />
616
- <UAvatar
617
- v-else
618
- :aria-label="item.name"
619
- :image="item.profilePictureUrl"
620
- :round="true"
621
- size="md"
622
- :showIndicator="false"
623
- />
624
- </q-item-section>
625
-
626
- <q-item-section>
627
- <q-item-label class="text-caption-md wrapped-text">
628
- {{ item?.name }}
629
- </q-item-label>
630
- <q-item-label
631
- class="text-body-xs text-neutral-9 label wrapped-text"
632
- >
633
- {{ item?.description }}
634
- </q-item-label>
635
- </q-item-section>
599
+ <q-list class="search-list q-mt-xs">
600
+ <div
601
+ v-if="showRecentSelected && recentSearchesLoading"
602
+ class="row justify-between items-center"
603
+ >
604
+ <span class="text-overline-xs"> Recently Selected </span>
636
605
 
637
- <q-item-section side>
638
- <UBtnStd
639
- v-bind="item.btnProps"
640
- :color="item.btnProps?.color ?? 'primary'"
641
- :label="actionButtonLabel"
642
- outline
643
- size="sm"
644
- @click.stop="onItemActionClick(item)"
645
- />
646
- </q-item-section>
647
- </q-item>
648
- </template>
606
+ <q-spinner
607
+ v-if="recentSearchesLoading"
608
+ color="grey-14"
609
+ size="1rem"
610
+ />
611
+ </div>
612
+ <div
613
+ v-if="showRecentSelected && recentSearches && recentSearches.length"
614
+ >
615
+ <span class="text-overline-xs"> Recently Selected </span>
616
+
617
+ <template v-for="item in recentSearches" :key="item.id">
618
+ <q-item class="list-item" clickable>
619
+ <q-item-section side>
620
+ <UAvatar
621
+ v-if="
622
+ !item.profilePictureUrl ||
623
+ item.profilePictureUrl?.nullValue === 0
624
+ "
625
+ :aria-label="item.name"
626
+ :name="parseInitials(item.name)"
627
+ size="md"
628
+ />
629
+ <UAvatar
630
+ v-else
631
+ :aria-label="item.name"
632
+ :image="item.profilePictureUrl"
633
+ :round="true"
634
+ size="md"
635
+ :showIndicator="false"
636
+ />
637
+ </q-item-section>
638
+
639
+ <q-item-section>
640
+ <q-item-label class="text-caption-md wrapped-text">
641
+ {{ item?.name }}
642
+ </q-item-label>
643
+ <q-item-label
644
+ class="text-body-xs text-neutral-9 label wrapped-text"
645
+ >
646
+ {{ item?.description }}
647
+ </q-item-label>
648
+ </q-item-section>
649
+
650
+ <q-item-section side>
651
+ <UBtnStd
652
+ v-bind="item.btnProps"
653
+ :color="item.btnProps?.color ?? 'primary'"
654
+ :disable="item.disable"
655
+ :label="actionButtonLabel"
656
+ :loading="actionButtonLoading"
657
+ outline
658
+ size="sm"
659
+ @click.stop="onItemActionClick(item)"
660
+ >
661
+ <template v-if="item.tooltip && item.disable" #tooltip>
662
+ <UTooltip
663
+ anchor="top middle"
664
+ :description="item.tooltip"
665
+ :offset="[0, 4]"
666
+ self="bottom middle"
667
+ />
668
+ </template>
669
+ </UBtnStd>
670
+ </q-item-section>
671
+ </q-item>
672
+ </template>
673
+ </div>
649
674
  </q-list>
650
675
  </div>
651
676
  </q-list>
@@ -683,14 +708,6 @@ watch(
683
708
  display: flex
684
709
  flex-direction: column
685
710
  gap: $xxs
686
- .searchText-md
687
- flex: 1
688
- word-wrap: break-word
689
- min-width: 18.5rem
690
- .searchText-sm
691
- flex: 1
692
- word-wrap: break-word
693
- min-width: 16.5rem
694
711
  .list-item
695
712
  border-radius: $xs
696
713
  padding: $xs
@@ -706,5 +723,4 @@ watch(
706
723
  white-space: normal
707
724
  overflow: hidden
708
725
  word-wrap: break-word
709
- max-width: 18rem
710
726
  </style>