@asd20/ui-next 2.2.0 → 2.2.2
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 +14 -0
- package/package.json +1 -1
- package/src/components/organisms/Asd20FileList/index.vue +95 -74
- package/src/components/organisms/Asd20List/index.vue +43 -3
- package/src/components/organisms/Asd20SiteSearch/index.vue +29 -18
- package/src/components/organisms/Asd20WidgetList/index.vue +43 -3
- package/src/helpers/logSearchAnalytics.js +16 -4
- package/src/helpers/queryAiSite.js +9 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.2.2](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.2.1...ui-next-v2.2.2) (2026-04-13)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* fix log search analytics not executing ([5c94742](https://github.com/academydistrict20/asd20-ui-next/commit/5c94742ed63517c5f5ba918583b052606951a842))
|
|
9
|
+
|
|
10
|
+
## [2.2.1](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.2.0...ui-next-v2.2.1) (2026-04-07)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* fix file header text being dropped ([cb07594](https://github.com/academydistrict20/asd20-ui-next/commit/cb075946768dd58fb39ceed08ae406a1c36a532f))
|
|
16
|
+
|
|
3
17
|
# [2.2.0](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.1.0...ui-next-v2.2.0) (2026-04-07)
|
|
4
18
|
|
|
5
19
|
|
package/package.json
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
v-bind="$attrs"
|
|
4
4
|
ref="listComponent"
|
|
5
5
|
role="region"
|
|
6
|
-
:aria-label="
|
|
6
|
+
:aria-label="resolvedTitle"
|
|
7
7
|
class="asd20-file-list"
|
|
8
8
|
:max-height="maxHeight"
|
|
9
|
-
:headline="
|
|
9
|
+
:headline="resolvedTitle"
|
|
10
10
|
:icon="icon"
|
|
11
11
|
:column-width="640"
|
|
12
12
|
>
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
v-model="searchQuery"
|
|
20
20
|
class="asd20-file-list__search"
|
|
21
21
|
:placeholder="searchPlaceholder"
|
|
22
|
-
:extra="resultSummary"
|
|
23
22
|
:id-tag="searchIdTag"
|
|
24
23
|
/>
|
|
25
24
|
</div>
|
|
@@ -142,6 +141,7 @@ export default {
|
|
|
142
141
|
props: {
|
|
143
142
|
files: { type: Array, default: () => [] },
|
|
144
143
|
title: { type: String, default: '' },
|
|
144
|
+
headline: { type: String, default: '' },
|
|
145
145
|
icon: { type: String, default: '' },
|
|
146
146
|
url: { type: String, default: '' },
|
|
147
147
|
groupByOwner: { type: Boolean, default: false },
|
|
@@ -166,6 +166,10 @@ export default {
|
|
|
166
166
|
}),
|
|
167
167
|
|
|
168
168
|
computed: {
|
|
169
|
+
resolvedTitle() {
|
|
170
|
+
return this.title || this.headline
|
|
171
|
+
},
|
|
172
|
+
|
|
169
173
|
computedFiles() {
|
|
170
174
|
return (this.files || []).concat(this.loadedFiles)
|
|
171
175
|
},
|
|
@@ -230,13 +234,6 @@ export default {
|
|
|
230
234
|
return this.filteredFiles.slice(0, this.effectiveVisibleCount)
|
|
231
235
|
},
|
|
232
236
|
|
|
233
|
-
paginatedFiles() {
|
|
234
|
-
if (!this.paginate) return this.visibleFiles
|
|
235
|
-
|
|
236
|
-
const startIndex = (this.currentPage - 1) * this.resolvedPageSize
|
|
237
|
-
return this.filteredFiles.slice(startIndex, startIndex + this.resolvedPageSize)
|
|
238
|
-
},
|
|
239
|
-
|
|
240
237
|
canShowMore() {
|
|
241
238
|
return (
|
|
242
239
|
!!this.initialVisibleCount &&
|
|
@@ -261,16 +258,6 @@ export default {
|
|
|
261
258
|
: this.initialVisibleCount || 50
|
|
262
259
|
},
|
|
263
260
|
|
|
264
|
-
resultSummary() {
|
|
265
|
-
if (!this.searchable) return ''
|
|
266
|
-
if (!this.totalFilesCount) return '0 files'
|
|
267
|
-
if (this.hasActiveSearch) {
|
|
268
|
-
return `${this.filteredFilesCount} of ${this.totalFilesCount}`
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
return `${this.totalFilesCount} files`
|
|
272
|
-
},
|
|
273
|
-
|
|
274
261
|
footerSummary() {
|
|
275
262
|
if (!this.totalFilesCount) return ''
|
|
276
263
|
|
|
@@ -306,7 +293,7 @@ export default {
|
|
|
306
293
|
},
|
|
307
294
|
|
|
308
295
|
searchIdTag() {
|
|
309
|
-
return normalizeSearchText(this.
|
|
296
|
+
return normalizeSearchText(this.resolvedTitle).replace(/\s+/g, '-')
|
|
310
297
|
},
|
|
311
298
|
|
|
312
299
|
emptyStateMessage() {
|
|
@@ -344,7 +331,7 @@ export default {
|
|
|
344
331
|
return `Showing ${this.filteredFilesCount} files.`
|
|
345
332
|
},
|
|
346
333
|
|
|
347
|
-
|
|
334
|
+
groupedFileItems() {
|
|
348
335
|
if (this.groupByDate) {
|
|
349
336
|
return this.fileItemsGroupedByDate
|
|
350
337
|
} else if (this.groupByOwner) {
|
|
@@ -357,8 +344,41 @@ export default {
|
|
|
357
344
|
return this.fileItemsGroupedByCategory
|
|
358
345
|
},
|
|
359
346
|
|
|
347
|
+
paginatedGroupEntries() {
|
|
348
|
+
const entries = this.groupedFileItems.flatMap(group =>
|
|
349
|
+
group.items.map(item => ({
|
|
350
|
+
name: group.name,
|
|
351
|
+
item,
|
|
352
|
+
}))
|
|
353
|
+
)
|
|
354
|
+
|
|
355
|
+
if (!this.paginate) return entries
|
|
356
|
+
|
|
357
|
+
const startIndex = (this.currentPage - 1) * this.resolvedPageSize
|
|
358
|
+
return entries.slice(startIndex, startIndex + this.resolvedPageSize)
|
|
359
|
+
},
|
|
360
|
+
|
|
361
|
+
categorizedFileItems() {
|
|
362
|
+
if (!this.paginate) return this.groupedFileItems
|
|
363
|
+
|
|
364
|
+
return this.paginatedGroupEntries.reduce((groups, entry) => {
|
|
365
|
+
const existingGroup = groups.find(group => group.name === entry.name)
|
|
366
|
+
|
|
367
|
+
if (existingGroup) {
|
|
368
|
+
existingGroup.items.push(entry.item)
|
|
369
|
+
return groups
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
groups.push({
|
|
373
|
+
name: entry.name,
|
|
374
|
+
items: [entry.item],
|
|
375
|
+
})
|
|
376
|
+
return groups
|
|
377
|
+
}, [])
|
|
378
|
+
},
|
|
379
|
+
|
|
360
380
|
fileItemsGroupedByCategory() {
|
|
361
|
-
return this.
|
|
381
|
+
return this.visibleFiles
|
|
362
382
|
.reduce((a, c) => {
|
|
363
383
|
let categories =
|
|
364
384
|
c.categories && c.categories.length > 0
|
|
@@ -373,21 +393,19 @@ export default {
|
|
|
373
393
|
.map(c => {
|
|
374
394
|
return {
|
|
375
395
|
name: c,
|
|
376
|
-
items:
|
|
377
|
-
|
|
378
|
-
.
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
.sort((a, b) =>
|
|
388
|
-
a.label > b.label ? 1 : b.label > a.label ? -1 : 0
|
|
396
|
+
items: this.sortMappedFileItems(
|
|
397
|
+
mapFilesToListItems(
|
|
398
|
+
this.visibleFiles
|
|
399
|
+
.map(f => ({
|
|
400
|
+
...f,
|
|
401
|
+
categories:
|
|
402
|
+
f.categories && f.categories.length > 0
|
|
403
|
+
? f.categories
|
|
404
|
+
: ['Uncategorized'],
|
|
405
|
+
}))
|
|
406
|
+
.filter(f => f.categories.indexOf(c) > -1)
|
|
389
407
|
)
|
|
390
|
-
|
|
408
|
+
).map(t => ({
|
|
391
409
|
...t,
|
|
392
410
|
bordered: false,
|
|
393
411
|
alignTop: false,
|
|
@@ -399,7 +417,7 @@ export default {
|
|
|
399
417
|
},
|
|
400
418
|
|
|
401
419
|
fileItemsGroupedByCategoryDescending() {
|
|
402
|
-
return this.
|
|
420
|
+
return this.visibleFiles
|
|
403
421
|
.reduce((a, c) => {
|
|
404
422
|
let categories =
|
|
405
423
|
c.categories && c.categories.length > 0
|
|
@@ -414,21 +432,19 @@ export default {
|
|
|
414
432
|
.map(c => {
|
|
415
433
|
return {
|
|
416
434
|
name: c,
|
|
417
|
-
items:
|
|
418
|
-
|
|
419
|
-
.
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
.sort((a, b) =>
|
|
429
|
-
a.label > b.label ? 1 : b.label > a.label ? -1 : 0
|
|
435
|
+
items: this.sortMappedFileItems(
|
|
436
|
+
mapFilesToListItems(
|
|
437
|
+
this.visibleFiles
|
|
438
|
+
.map(f => ({
|
|
439
|
+
...f,
|
|
440
|
+
categories:
|
|
441
|
+
f.categories && f.categories.length > 0
|
|
442
|
+
? f.categories
|
|
443
|
+
: ['Uncategorized'],
|
|
444
|
+
}))
|
|
445
|
+
.filter(f => f.categories.indexOf(c) > -1)
|
|
430
446
|
)
|
|
431
|
-
|
|
447
|
+
).map(t => ({
|
|
432
448
|
...t,
|
|
433
449
|
bordered: false,
|
|
434
450
|
alignTop: false,
|
|
@@ -440,7 +456,7 @@ export default {
|
|
|
440
456
|
},
|
|
441
457
|
|
|
442
458
|
fileItemsGroupedByTag() {
|
|
443
|
-
return this.
|
|
459
|
+
return this.visibleFiles
|
|
444
460
|
.reduce((a, t) => {
|
|
445
461
|
let tags = t.tags && t.tags.length > 0 ? t.tags : ['Untagged']
|
|
446
462
|
for (const tag of tags) {
|
|
@@ -452,18 +468,16 @@ export default {
|
|
|
452
468
|
.map(t => {
|
|
453
469
|
return {
|
|
454
470
|
name: t,
|
|
455
|
-
items:
|
|
456
|
-
|
|
457
|
-
.
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
.sort((a, b) =>
|
|
464
|
-
a.label > b.label ? 1 : b.label > a.label ? -1 : 0
|
|
471
|
+
items: this.sortMappedFileItems(
|
|
472
|
+
mapFilesToListItems(
|
|
473
|
+
this.visibleFiles
|
|
474
|
+
.map(f => ({
|
|
475
|
+
...f,
|
|
476
|
+
tags: f.tags && f.tags.length > 0 ? f.tags : ['Untagged'],
|
|
477
|
+
}))
|
|
478
|
+
.filter(f => f.tags.indexOf(t) > -1)
|
|
465
479
|
)
|
|
466
|
-
|
|
480
|
+
).map(t => ({
|
|
467
481
|
...t,
|
|
468
482
|
bordered: false,
|
|
469
483
|
alignTop: false,
|
|
@@ -475,7 +489,7 @@ export default {
|
|
|
475
489
|
},
|
|
476
490
|
|
|
477
491
|
fileItemsGroupedByDate() {
|
|
478
|
-
return this.
|
|
492
|
+
return this.visibleFiles
|
|
479
493
|
.reduce((a, c) => {
|
|
480
494
|
let date = new Date(c.lastModifiedDateTime).toLocaleDateString()
|
|
481
495
|
if (a.indexOf(date) === -1) a.push(date)
|
|
@@ -485,15 +499,13 @@ export default {
|
|
|
485
499
|
return {
|
|
486
500
|
name: d,
|
|
487
501
|
unix: new Date(d).valueOf(),
|
|
488
|
-
items:
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
.sort((a, b) =>
|
|
494
|
-
a.label > b.label ? 1 : b.label > a.label ? -1 : 0
|
|
502
|
+
items: this.sortMappedFileItems(
|
|
503
|
+
mapFilesToListItems(
|
|
504
|
+
this.visibleFiles.filter(
|
|
505
|
+
f => new Date(f.lastModifiedDateTime).toLocaleDateString() === d
|
|
506
|
+
)
|
|
495
507
|
)
|
|
496
|
-
|
|
508
|
+
).map(t => ({
|
|
497
509
|
...t,
|
|
498
510
|
bordered: false,
|
|
499
511
|
alignTop: false,
|
|
@@ -508,7 +520,9 @@ export default {
|
|
|
508
520
|
fileItemsGroupedByOwner() {
|
|
509
521
|
return [
|
|
510
522
|
{
|
|
511
|
-
items:
|
|
523
|
+
items: this.sortMappedFileItems(
|
|
524
|
+
mapFilesToListItems(this.visibleFiles)
|
|
525
|
+
).map(t => ({
|
|
512
526
|
...t,
|
|
513
527
|
bordered: false,
|
|
514
528
|
alignTop: false,
|
|
@@ -584,6 +598,13 @@ export default {
|
|
|
584
598
|
const haystack = this.getFileSearchTokens(file)
|
|
585
599
|
return this.searchTerms.every(term => haystack.includes(term))
|
|
586
600
|
},
|
|
601
|
+
sortMappedFileItems(items = []) {
|
|
602
|
+
return [...items].sort((a, b) => {
|
|
603
|
+
const left = String(a.label || '').toLowerCase()
|
|
604
|
+
const right = String(b.label || '').toLowerCase()
|
|
605
|
+
return left.localeCompare(right)
|
|
606
|
+
})
|
|
607
|
+
},
|
|
587
608
|
// Expose the checkForOverflow method from the asd20viewport component
|
|
588
609
|
// Expose the handleResize method from the asd20list component
|
|
589
610
|
checkForOverflow() {
|
|
@@ -17,11 +17,51 @@
|
|
|
17
17
|
:name="icon"
|
|
18
18
|
:size="iconSize"
|
|
19
19
|
/>
|
|
20
|
-
<
|
|
21
|
-
|
|
20
|
+
<h1
|
|
21
|
+
v-if="headlineTag === 'h1'"
|
|
22
22
|
class="asd20-list__headline"
|
|
23
23
|
v-html="headline"
|
|
24
|
-
></
|
|
24
|
+
></h1>
|
|
25
|
+
<h2
|
|
26
|
+
v-else-if="headlineTag === 'h2'"
|
|
27
|
+
class="asd20-list__headline"
|
|
28
|
+
v-html="headline"
|
|
29
|
+
></h2>
|
|
30
|
+
<h3
|
|
31
|
+
v-else-if="headlineTag === 'h3'"
|
|
32
|
+
class="asd20-list__headline"
|
|
33
|
+
v-html="headline"
|
|
34
|
+
></h3>
|
|
35
|
+
<h4
|
|
36
|
+
v-else-if="headlineTag === 'h4'"
|
|
37
|
+
class="asd20-list__headline"
|
|
38
|
+
v-html="headline"
|
|
39
|
+
></h4>
|
|
40
|
+
<h5
|
|
41
|
+
v-else-if="headlineTag === 'h5'"
|
|
42
|
+
class="asd20-list__headline"
|
|
43
|
+
v-html="headline"
|
|
44
|
+
></h5>
|
|
45
|
+
<h6
|
|
46
|
+
v-else-if="headlineTag === 'h6'"
|
|
47
|
+
class="asd20-list__headline"
|
|
48
|
+
v-html="headline"
|
|
49
|
+
></h6>
|
|
50
|
+
<p
|
|
51
|
+
v-else-if="headlineTag === 'p'"
|
|
52
|
+
class="asd20-list__headline"
|
|
53
|
+
v-html="headline"
|
|
54
|
+
></p>
|
|
55
|
+
<span
|
|
56
|
+
v-else-if="headlineTag === 'span'"
|
|
57
|
+
class="asd20-list__headline"
|
|
58
|
+
v-html="headline"
|
|
59
|
+
></span>
|
|
60
|
+
<div
|
|
61
|
+
v-else
|
|
62
|
+
class="asd20-list__headline"
|
|
63
|
+
v-html="headline"
|
|
64
|
+
></div>
|
|
25
65
|
</div>
|
|
26
66
|
<slot name="header" />
|
|
27
67
|
</div>
|
|
@@ -979,8 +979,9 @@ export default {
|
|
|
979
979
|
},
|
|
980
980
|
feedbackFormUrlRaw() {
|
|
981
981
|
if (this.aiSearchFeedbackFormUrl) return this.aiSearchFeedbackFormUrl
|
|
982
|
-
|
|
983
|
-
|
|
982
|
+
const runtimeConfig = this.resolveRuntimeConfig()
|
|
983
|
+
if (runtimeConfig.aiSearchFeedbackFormUrl)
|
|
984
|
+
return runtimeConfig.aiSearchFeedbackFormUrl
|
|
984
985
|
return ''
|
|
985
986
|
},
|
|
986
987
|
|
|
@@ -2213,6 +2214,28 @@ export default {
|
|
|
2213
2214
|
this.$emit('update:active', false)
|
|
2214
2215
|
},
|
|
2215
2216
|
|
|
2217
|
+
resolveRuntimeConfig() {
|
|
2218
|
+
const runtimeConfig =
|
|
2219
|
+
this.$config ||
|
|
2220
|
+
this.$store?.$config ||
|
|
2221
|
+
this.$?.appContext?.config?.globalProperties?.$config ||
|
|
2222
|
+
{}
|
|
2223
|
+
|
|
2224
|
+
if (
|
|
2225
|
+
runtimeConfig.public &&
|
|
2226
|
+
typeof runtimeConfig.public === 'object' &&
|
|
2227
|
+
!Array.isArray(runtimeConfig.public)
|
|
2228
|
+
) {
|
|
2229
|
+
return runtimeConfig.public
|
|
2230
|
+
}
|
|
2231
|
+
|
|
2232
|
+
return runtimeConfig
|
|
2233
|
+
},
|
|
2234
|
+
|
|
2235
|
+
resolveFunctionsEndpoint() {
|
|
2236
|
+
return this.resolveRuntimeConfig().functionsEndpoint || ''
|
|
2237
|
+
},
|
|
2238
|
+
|
|
2216
2239
|
toggleKeywords(turnId) {
|
|
2217
2240
|
this.expandedKeywordsTurnId =
|
|
2218
2241
|
this.expandedKeywordsTurnId === turnId ? null : turnId
|
|
@@ -2253,10 +2276,7 @@ export default {
|
|
|
2253
2276
|
const response = await logSearchFeedback({
|
|
2254
2277
|
searchLogId: turn.searchLogId,
|
|
2255
2278
|
feedbackValue,
|
|
2256
|
-
functionsEndpoint:
|
|
2257
|
-
this.$config && this.$config.functionsEndpoint
|
|
2258
|
-
? this.$config.functionsEndpoint
|
|
2259
|
-
: null,
|
|
2279
|
+
functionsEndpoint: this.resolveFunctionsEndpoint() || null,
|
|
2260
2280
|
})
|
|
2261
2281
|
|
|
2262
2282
|
if (response && response.ok) {
|
|
@@ -2330,10 +2350,7 @@ export default {
|
|
|
2330
2350
|
const response = await logSearchFeedback({
|
|
2331
2351
|
searchLogId: targetTurn.searchLogId,
|
|
2332
2352
|
improvementFeedback,
|
|
2333
|
-
functionsEndpoint:
|
|
2334
|
-
this.$config && this.$config.functionsEndpoint
|
|
2335
|
-
? this.$config.functionsEndpoint
|
|
2336
|
-
: null,
|
|
2353
|
+
functionsEndpoint: this.resolveFunctionsEndpoint() || null,
|
|
2337
2354
|
})
|
|
2338
2355
|
|
|
2339
2356
|
if (response && response.ok) {
|
|
@@ -2543,10 +2560,7 @@ export default {
|
|
|
2543
2560
|
: null,
|
|
2544
2561
|
languageCode: this.getSearchLanguageCode(),
|
|
2545
2562
|
isFollowup: false,
|
|
2546
|
-
functionsEndpoint:
|
|
2547
|
-
this.$config && this.$config.functionsEndpoint
|
|
2548
|
-
? this.$config.functionsEndpoint
|
|
2549
|
-
: null,
|
|
2563
|
+
functionsEndpoint: this.resolveFunctionsEndpoint() || null,
|
|
2550
2564
|
})
|
|
2551
2565
|
}
|
|
2552
2566
|
},
|
|
@@ -2797,10 +2811,7 @@ export default {
|
|
|
2797
2811
|
: null,
|
|
2798
2812
|
languageCode: this.getSearchLanguageCode(),
|
|
2799
2813
|
isFollowup: isFollowUpQuestion,
|
|
2800
|
-
functionsEndpoint:
|
|
2801
|
-
this.$config && this.$config.functionsEndpoint
|
|
2802
|
-
? this.$config.functionsEndpoint
|
|
2803
|
-
: null,
|
|
2814
|
+
functionsEndpoint: this.resolveFunctionsEndpoint() || null,
|
|
2804
2815
|
aiResponse: assistantResponseForAnalytics || null,
|
|
2805
2816
|
})
|
|
2806
2817
|
if (assistantTurnId) {
|
|
@@ -17,11 +17,51 @@
|
|
|
17
17
|
:name="icon"
|
|
18
18
|
:size="iconSize"
|
|
19
19
|
/>
|
|
20
|
-
<
|
|
21
|
-
|
|
20
|
+
<h1
|
|
21
|
+
v-if="headlineTag === 'h1'"
|
|
22
22
|
class="asd20-list__headline"
|
|
23
23
|
v-html="headline"
|
|
24
|
-
></
|
|
24
|
+
></h1>
|
|
25
|
+
<h2
|
|
26
|
+
v-else-if="headlineTag === 'h2'"
|
|
27
|
+
class="asd20-list__headline"
|
|
28
|
+
v-html="headline"
|
|
29
|
+
></h2>
|
|
30
|
+
<h3
|
|
31
|
+
v-else-if="headlineTag === 'h3'"
|
|
32
|
+
class="asd20-list__headline"
|
|
33
|
+
v-html="headline"
|
|
34
|
+
></h3>
|
|
35
|
+
<h4
|
|
36
|
+
v-else-if="headlineTag === 'h4'"
|
|
37
|
+
class="asd20-list__headline"
|
|
38
|
+
v-html="headline"
|
|
39
|
+
></h4>
|
|
40
|
+
<h5
|
|
41
|
+
v-else-if="headlineTag === 'h5'"
|
|
42
|
+
class="asd20-list__headline"
|
|
43
|
+
v-html="headline"
|
|
44
|
+
></h5>
|
|
45
|
+
<h6
|
|
46
|
+
v-else-if="headlineTag === 'h6'"
|
|
47
|
+
class="asd20-list__headline"
|
|
48
|
+
v-html="headline"
|
|
49
|
+
></h6>
|
|
50
|
+
<p
|
|
51
|
+
v-else-if="headlineTag === 'p'"
|
|
52
|
+
class="asd20-list__headline"
|
|
53
|
+
v-html="headline"
|
|
54
|
+
></p>
|
|
55
|
+
<span
|
|
56
|
+
v-else-if="headlineTag === 'span'"
|
|
57
|
+
class="asd20-list__headline"
|
|
58
|
+
v-html="headline"
|
|
59
|
+
></span>
|
|
60
|
+
<div
|
|
61
|
+
v-else
|
|
62
|
+
class="asd20-list__headline"
|
|
63
|
+
v-html="headline"
|
|
64
|
+
></div>
|
|
25
65
|
</div>
|
|
26
66
|
<slot name="header" />
|
|
27
67
|
</div>
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import axios from 'axios'
|
|
2
2
|
|
|
3
|
+
function resolveNuxtWindowConfig() {
|
|
4
|
+
if (typeof window === 'undefined' || !window.__NUXT__) return {}
|
|
5
|
+
|
|
6
|
+
const runtimeConfig = window.__NUXT__.config
|
|
7
|
+
return runtimeConfig && typeof runtimeConfig === 'object' ? runtimeConfig : {}
|
|
8
|
+
}
|
|
9
|
+
|
|
3
10
|
export function resolveFunctionsEndpoint(payload) {
|
|
4
11
|
const explicitEndpoint =
|
|
5
12
|
payload && typeof payload.functionsEndpoint === 'string'
|
|
@@ -13,10 +20,15 @@ export function resolveFunctionsEndpoint(payload) {
|
|
|
13
20
|
if (processEndpoint) return processEndpoint
|
|
14
21
|
}
|
|
15
22
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
23
|
+
const nuxtConfig = resolveNuxtWindowConfig()
|
|
24
|
+
const nuxtEndpoints = [
|
|
25
|
+
nuxtConfig.functionsEndpoint,
|
|
26
|
+
nuxtConfig.public && nuxtConfig.public.functionsEndpoint,
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
for (const candidate of nuxtEndpoints) {
|
|
30
|
+
if (typeof candidate === 'string' && candidate.trim()) {
|
|
31
|
+
return candidate.trim()
|
|
20
32
|
}
|
|
21
33
|
}
|
|
22
34
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// helpers/search/queryAiSite.js
|
|
2
2
|
import axios from 'axios'
|
|
3
3
|
|
|
4
|
+
import { resolveFunctionsEndpoint } from './logSearchAnalytics'
|
|
5
|
+
|
|
4
6
|
/**
|
|
5
7
|
* Calls Azure Function / API for AI site search.
|
|
6
8
|
* Expected response shape:
|
|
@@ -14,14 +16,20 @@ export default async function queryAiSite({
|
|
|
14
16
|
organizationId = null,
|
|
15
17
|
organizationWebsite = null,
|
|
16
18
|
includeDistrictResults = true,
|
|
19
|
+
functionsEndpoint = null,
|
|
17
20
|
}) {
|
|
18
21
|
const q = (question || '').trim()
|
|
19
22
|
if (!q) {
|
|
20
23
|
return { answer: null, sources: [] }
|
|
21
24
|
}
|
|
22
25
|
|
|
26
|
+
const endpoint = resolveFunctionsEndpoint({ functionsEndpoint })
|
|
27
|
+
if (!endpoint) {
|
|
28
|
+
throw new Error('functionsEndpoint is required for AI site search.')
|
|
29
|
+
}
|
|
30
|
+
|
|
23
31
|
const { data } = await axios.post(
|
|
24
|
-
|
|
32
|
+
endpoint.replace(/\/$/, '') + '/ai-site-search',
|
|
25
33
|
{
|
|
26
34
|
question: q,
|
|
27
35
|
organizationId,
|