@asd20/ui-next 2.12.0 → 2.12.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.12.1](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.12.0...ui-next-v2.12.1) (2026-05-26)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * add group matches to people searches by keyword ([1edabb4](https://github.com/academydistrict20/asd20-ui-next/commit/1edabb458ead8430e04375cdb00071db345605f3))
9
+
3
10
  # [2.12.0](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.11.1...ui-next-v2.12.0) (2026-05-26)
4
11
 
5
12
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asd20/ui-next",
3
- "version": "2.12.0",
3
+ "version": "2.12.1",
4
4
  "private": false,
5
5
  "description": "ASD20 UI component library for Vue 3.",
6
6
  "license": "MIT",
@@ -1357,21 +1357,78 @@ export default {
1357
1357
  async queryPeopleWithFallback(payload) {
1358
1358
  if (typeof this.queryPeopleHandler === 'function') {
1359
1359
  const result = await this.queryPeopleHandler(payload)
1360
- if (Array.isArray(result)) return result
1361
- return result && Array.isArray(result.people) ? result.people : []
1360
+ if (Array.isArray(result)) {
1361
+ return { people: result, groups: [] }
1362
+ }
1363
+ return {
1364
+ people: result && Array.isArray(result.people) ? result.people : [],
1365
+ groups: result && Array.isArray(result.groups) ? result.groups : [],
1366
+ }
1362
1367
  }
1363
1368
 
1364
1369
  const searchStore = this.getSearchStore()
1365
1370
  if (searchStore) {
1366
- await searchStore.dispatch('search/queryPeople', payload)
1367
- return Array.isArray(this.resolvedPeople) ? this.resolvedPeople : []
1371
+ const result = await searchStore.dispatch('search/queryPeople', payload)
1372
+ return {
1373
+ people:
1374
+ result && Array.isArray(result.people)
1375
+ ? result.people
1376
+ : Array.isArray(this.resolvedPeople)
1377
+ ? this.resolvedPeople
1378
+ : [],
1379
+ groups: result && Array.isArray(result.groups) ? result.groups : [],
1380
+ }
1368
1381
  }
1369
1382
 
1370
1383
  const { people } = await queryPeople({
1371
1384
  ...payload,
1372
1385
  runtimeConfig: this.resolveRuntimeConfig(),
1373
1386
  })
1374
- return Array.isArray(people) ? people : []
1387
+ return {
1388
+ people: Array.isArray(people) ? people : [],
1389
+ groups: [],
1390
+ }
1391
+ },
1392
+
1393
+ getContactGroupKey(group = {}) {
1394
+ return String(group.id || group.title || group.contactEmail || '').trim()
1395
+ },
1396
+
1397
+ mergeContactGroups(primaryGroups = [], relatedGroups = []) {
1398
+ const merged = []
1399
+ const keyedIndexes = new Map()
1400
+ const addGroup = group => {
1401
+ if (!group || typeof group !== 'object') return
1402
+ const key = this.getContactGroupKey(group)
1403
+ if (!key) return
1404
+
1405
+ if (keyedIndexes.has(key)) {
1406
+ const existingIndex = keyedIndexes.get(key)
1407
+ const existing = merged[existingIndex]
1408
+ if (
1409
+ existing &&
1410
+ existing.relatedPersonMatch &&
1411
+ !group.relatedPersonMatch
1412
+ ) {
1413
+ merged[existingIndex] = group
1414
+ }
1415
+ return
1416
+ }
1417
+
1418
+ keyedIndexes.set(key, merged.length)
1419
+ merged.push(group)
1420
+ }
1421
+
1422
+ primaryGroups.forEach(addGroup)
1423
+ relatedGroups.forEach(addGroup)
1424
+
1425
+ return merged
1426
+ },
1427
+
1428
+ getDirectContactGroups() {
1429
+ return (this.currentGroups || []).filter(
1430
+ group => !(group && group.relatedPersonMatch)
1431
+ )
1375
1432
  },
1376
1433
 
1377
1434
  isLocalDevelopmentHost(hostname = '') {
@@ -2587,8 +2644,27 @@ export default {
2587
2644
  return ownerFilters
2588
2645
  },
2589
2646
 
2647
+ selectBestKeywordTabAfterContactResults({ runId, text } = {}) {
2648
+ if (!this.isCurrentSearchRun(runId)) return
2649
+ if (this.searchMode !== 'keyword') return
2650
+ if (this.currentTab !== 'Pages') return
2651
+ if (this.currentPages.length > 0 || this.contactResultCount === 0)
2652
+ return
2653
+
2654
+ this.currentTab = 'Contacts'
2655
+ this.syncSearchState({
2656
+ text: text || this.searchQuestion || this.inputText,
2657
+ mode: 'keyword',
2658
+ tab: 'Contacts',
2659
+ })
2660
+ this.$nextTick(() => this.refreshResultsScrollLayer())
2661
+ },
2662
+
2590
2663
  async searchGroups(options = {}) {
2591
2664
  const runId = options.runId || this.searchRunId
2665
+ const existingRelatedGroups = (this.currentGroups || []).filter(
2666
+ group => group && group.relatedPersonMatch
2667
+ )
2592
2668
  const searchInput = {
2593
2669
  keywords: this.keywords,
2594
2670
  question: this.searchQuestion || this.inputText,
@@ -2603,16 +2679,24 @@ export default {
2603
2679
  if (!this.isCurrentSearchRun(runId)) {
2604
2680
  return Array.from(
2605
2681
  new Set(
2606
- this.currentGroups
2682
+ this.getDirectContactGroups()
2607
2683
  .map(group => (group && group.title ? group.title.trim() : ''))
2608
2684
  .filter(Boolean)
2609
2685
  )
2610
2686
  )
2611
2687
  }
2688
+ if (existingRelatedGroups.length > 0) {
2689
+ this.setSearchResults({
2690
+ groups: this.mergeContactGroups(
2691
+ this.currentGroups,
2692
+ existingRelatedGroups
2693
+ ),
2694
+ })
2695
+ }
2612
2696
  this.persistSearchCacheSnapshot()
2613
2697
  return Array.from(
2614
2698
  new Set(
2615
- (this.currentGroups || [])
2699
+ this.getDirectContactGroups()
2616
2700
  .map(group => (group && group.title ? group.title.trim() : ''))
2617
2701
  .filter(Boolean)
2618
2702
  )
@@ -2629,13 +2713,27 @@ export default {
2629
2713
  this.searchingPeople = true
2630
2714
  try {
2631
2715
  let people = []
2716
+ let relatedGroups = []
2632
2717
  try {
2633
- people = await this.queryPeopleWithFallback(searchInput)
2718
+ const result = await this.queryPeopleWithFallback(searchInput)
2719
+ people = Array.isArray(result)
2720
+ ? result
2721
+ : result && Array.isArray(result.people)
2722
+ ? result.people
2723
+ : []
2724
+ relatedGroups =
2725
+ result && Array.isArray(result.groups) ? result.groups : []
2634
2726
  } catch (error) {
2635
2727
  people = []
2728
+ relatedGroups = []
2636
2729
  }
2637
2730
  if (!this.isCurrentSearchRun(runId)) return this.currentPeople
2638
2731
  this.setSearchResults({ people })
2732
+ if (relatedGroups.length > 0) {
2733
+ this.setSearchResults({
2734
+ groups: this.mergeContactGroups(this.currentGroups, relatedGroups),
2735
+ })
2736
+ }
2639
2737
  this.persistSearchCacheSnapshot()
2640
2738
  return this.currentPeople
2641
2739
  } finally {
@@ -2679,6 +2777,10 @@ export default {
2679
2777
  this.keywords = this.limitWords(text, 4)
2680
2778
  await this.searchPages({ keepAnswersTab: false, runId })
2681
2779
  this.searchFilesWithGroupOwners({ runId })
2780
+ .then(() =>
2781
+ this.selectBestKeywordTabAfterContactResults({ runId, text })
2782
+ )
2783
+ .catch(() => {})
2682
2784
  if (!this.isCurrentSearchRun(runId)) return
2683
2785
  this.currentTab = 'Pages'
2684
2786
  this.syncSearchState({ text, mode, tab: 'Pages' })