@asd20/ui 3.5.5 → 3.6.0
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 +1 -1
- package/src/components/organisms/Asd20SiteSearch/index.stories.js +2 -2
- package/src/components/organisms/Asd20SiteSearch/index.vue +291 -34
- package/src/components/templates/Asd20ClubsTemplate/index.vue +2 -0
- package/src/helpers/queryAiSite.js +45 -0
- package/src/store.js +11 -7
package/package.json
CHANGED
|
@@ -25,7 +25,7 @@ storiesOf('Organisms - Asd20SiteSearch', module).add(
|
|
|
25
25
|
pages: [{title: '1', description: 'adsfasdfasf', url: 'url', tags: ['one'] }],
|
|
26
26
|
files: [],
|
|
27
27
|
groups: [],
|
|
28
|
-
|
|
28
|
+
includeDistrictResults: true,
|
|
29
29
|
},
|
|
30
30
|
actions: {
|
|
31
31
|
queryPages({state, commit}, keywords) {
|
|
@@ -37,7 +37,7 @@ storiesOf('Organisms - Asd20SiteSearch', module).add(
|
|
|
37
37
|
queryGroups() {
|
|
38
38
|
console.log('queried groups')
|
|
39
39
|
},
|
|
40
|
-
|
|
40
|
+
setIncludeDistrictResults() {
|
|
41
41
|
console.log('setting district search toggle')
|
|
42
42
|
}
|
|
43
43
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
<template>
|
|
2
2
|
<div
|
|
3
3
|
ref="container"
|
|
4
4
|
class="asd20-site-search"
|
|
@@ -8,7 +8,41 @@
|
|
|
8
8
|
>
|
|
9
9
|
<div class="asd20-site-search__viewport">
|
|
10
10
|
<div class="asd20-site-search__options">
|
|
11
|
-
|
|
11
|
+
<!-- Ask a Question -->
|
|
12
|
+
<div class="asd20-site-search__field asd20-site-search__field--question">
|
|
13
|
+
<!-- <label class="asd20-site-search__label">Ask a question</label> -->
|
|
14
|
+
<div class="asd20-site-search__question-row">
|
|
15
|
+
<asd20-search-field
|
|
16
|
+
idTag="-question"
|
|
17
|
+
ref="question"
|
|
18
|
+
v-model="questionText"
|
|
19
|
+
@keyup.enter.stop.prevent="onAskQuestion"
|
|
20
|
+
placeholder="Ask a question."
|
|
21
|
+
/>
|
|
22
|
+
<button
|
|
23
|
+
type="button"
|
|
24
|
+
class="asd20-site-search__ask-button"
|
|
25
|
+
@click="onAskQuestion"
|
|
26
|
+
:disabled="!questionText || searchingAi"
|
|
27
|
+
>
|
|
28
|
+
Ask
|
|
29
|
+
</button>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
<hr/>
|
|
33
|
+
|
|
34
|
+
<!-- Search by Keyword -->
|
|
35
|
+
<div class="asd20-site-search__field asd20-site-search__field--keyword">
|
|
36
|
+
<!-- <label class="asd20-site-search__label">Search by keyword</label> -->
|
|
37
|
+
<asd20-search-field
|
|
38
|
+
idTag="-sitewide"
|
|
39
|
+
ref="search"
|
|
40
|
+
v-model="keywords"
|
|
41
|
+
placeholder="Search by keyword."
|
|
42
|
+
/>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
<!-- Only show school results -->
|
|
12
46
|
<asd20-checkbox
|
|
13
47
|
v-show="hasParentOrg"
|
|
14
48
|
v-model="excludeDistrictResults"
|
|
@@ -17,29 +51,64 @@
|
|
|
17
51
|
label="Only show school results"
|
|
18
52
|
/>
|
|
19
53
|
</div>
|
|
54
|
+
|
|
20
55
|
<asd20-tab-bar :tabs="tabs" @tabClick="onTabClick" />
|
|
56
|
+
|
|
21
57
|
<asd20-viewport class="asd20-site-search__results" scrollable>
|
|
22
58
|
<asd20-notification
|
|
23
|
-
v-if="!keywords && !searchingFiles && !searchingPages"
|
|
24
|
-
title="Search by Keyword"
|
|
25
|
-
description="
|
|
59
|
+
v-if="!keywords && !questionText && !searchingFiles && !searchingPages && !searchingAi"
|
|
60
|
+
title="Ask a Question, or Search by Keyword"
|
|
61
|
+
description="Use the top box for plain-language questions, or search by keyword in the box below."
|
|
26
62
|
/>
|
|
63
|
+
|
|
64
|
+
<!-- Pages tab -->
|
|
27
65
|
<div v-show="currentTab === 'Pages'" scrollable>
|
|
66
|
+
<!-- AI Answer Section -->
|
|
67
|
+
<div v-if="aiAnswer" class="asd20-site-search__ai-result">
|
|
68
|
+
<h3>Answer</h3>
|
|
69
|
+
<div class="asd20-site-search__ai-answer" v-html="aiAnswer" />
|
|
70
|
+
|
|
71
|
+
<div v-if="aiUiSources.length" class="asd20-site-search__ai-sources">
|
|
72
|
+
<h4>Sources</h4>
|
|
73
|
+
<ul>
|
|
74
|
+
<li v-for="src in aiUiSources" :key="src.url || src.id">
|
|
75
|
+
<strong>Content from: {{ src.hostLabel }}</strong><br />
|
|
76
|
+
<a :href="src.url" target="_blank" rel="noreferrer">
|
|
77
|
+
{{ src.title }}
|
|
78
|
+
</a>
|
|
79
|
+
<p v-if="src.snippet" class="asd20-site-search__ai-snippet">
|
|
80
|
+
{{ src.snippet }}
|
|
81
|
+
</p>
|
|
82
|
+
</li>
|
|
83
|
+
</ul>
|
|
84
|
+
</div>
|
|
85
|
+
|
|
86
|
+
<asd20-loader v-if="searchingAi" size="lg" />
|
|
87
|
+
</div>
|
|
88
|
+
|
|
89
|
+
<!-- No results -->
|
|
28
90
|
<asd20-notification
|
|
29
|
-
v-if="keywords && _pages.length === 0 && !searchingPages"
|
|
91
|
+
v-if="keywords && _pages.length === 0 && !searchingPages && !aiAnswer"
|
|
30
92
|
title="No Pages Found"
|
|
31
93
|
description="Try using different keywords."
|
|
32
94
|
/>
|
|
95
|
+
|
|
96
|
+
<!-- Results list -->
|
|
33
97
|
<asd20-list @click.native="dismiss">
|
|
34
98
|
<asd20-list-item
|
|
35
99
|
v-for="item in pageListItems"
|
|
36
100
|
:key="item.page.id"
|
|
37
|
-
:attribution="
|
|
101
|
+
:attribution="
|
|
102
|
+
organization.id !== '26eaf390-d8ab-11e9-a3a8-5de5bba4f125' &&
|
|
103
|
+
!excludeDistrictResults
|
|
104
|
+
"
|
|
38
105
|
v-bind="item"
|
|
39
106
|
/>
|
|
40
107
|
</asd20-list>
|
|
41
108
|
<asd20-loader v-if="searchingPages" size="lg" />
|
|
42
109
|
</div>
|
|
110
|
+
|
|
111
|
+
<!-- Files tab -->
|
|
43
112
|
<div v-show="currentTab === 'Files'" scrollable>
|
|
44
113
|
<asd20-notification
|
|
45
114
|
v-if="keywords && _files.length === 0 && !searchingFiles"
|
|
@@ -50,15 +119,16 @@
|
|
|
50
119
|
<asd20-loader v-if="searchingFiles" size="lg" />
|
|
51
120
|
</div>
|
|
52
121
|
</asd20-viewport>
|
|
122
|
+
|
|
53
123
|
<div class="asd20-site-search__suggested" v-if="_groups.length > 0">
|
|
54
|
-
<h3>
|
|
124
|
+
<h3>
|
|
125
|
+
{{ _groups.length > 1 ? 'Suggested Contacts:' : 'Suggested Contact:' }}
|
|
126
|
+
</h3>
|
|
55
127
|
<asd20-list-item
|
|
56
128
|
v-for="g in _groups"
|
|
57
129
|
:text-avatar="
|
|
58
130
|
g.abbreviation ||
|
|
59
|
-
((g.shortName || g.title || '')
|
|
60
|
-
.match(/\b([A-Z])/g) || [])
|
|
61
|
-
.join('')
|
|
131
|
+
((g.shortName || g.title || '').match(/\b([A-Z])/g) || []).join('')
|
|
62
132
|
"
|
|
63
133
|
:key="g.id"
|
|
64
134
|
:label="`${g.title}`"
|
|
@@ -67,6 +137,7 @@
|
|
|
67
137
|
/>
|
|
68
138
|
</div>
|
|
69
139
|
</div>
|
|
140
|
+
|
|
70
141
|
<asd20-modal
|
|
71
142
|
:open="!!selectedGroup"
|
|
72
143
|
title="Details"
|
|
@@ -130,8 +201,9 @@ export default {
|
|
|
130
201
|
},
|
|
131
202
|
'search'
|
|
132
203
|
),
|
|
204
|
+
// Make sure your search module state uses "includeDistrictResults"
|
|
133
205
|
globalPropMixinFactory(
|
|
134
|
-
'
|
|
206
|
+
'includeDistrictResults',
|
|
135
207
|
{
|
|
136
208
|
type: Boolean,
|
|
137
209
|
default: true,
|
|
@@ -156,17 +228,19 @@ export default {
|
|
|
156
228
|
|
|
157
229
|
props: {
|
|
158
230
|
active: { type: Boolean, default: false },
|
|
159
|
-
organization: {type: Object, default: {title:
|
|
231
|
+
organization: { type: Object, default: () => ({ title: 'Academy District 20' }) },
|
|
160
232
|
organizationOptions: { type: Array, default: () => [] },
|
|
161
233
|
},
|
|
162
234
|
|
|
163
235
|
data: () => ({
|
|
164
236
|
currentTab: 'Pages',
|
|
237
|
+
// keyword search (classic)
|
|
165
238
|
keywords: '',
|
|
166
|
-
//
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
239
|
+
// question input (AI)
|
|
240
|
+
questionText: '',
|
|
241
|
+
aiAnswer: null,
|
|
242
|
+
searchingAi: false,
|
|
243
|
+
aiSources: [],
|
|
170
244
|
selectedGroup: null,
|
|
171
245
|
searchingPages: false,
|
|
172
246
|
searchingFiles: false,
|
|
@@ -195,7 +269,7 @@ export default {
|
|
|
195
269
|
return {
|
|
196
270
|
...item,
|
|
197
271
|
sourceTitle,
|
|
198
|
-
logoUrl
|
|
272
|
+
logoUrl,
|
|
199
273
|
}
|
|
200
274
|
})
|
|
201
275
|
: []
|
|
@@ -222,37 +296,59 @@ export default {
|
|
|
222
296
|
return this._organization.parentOrganization !== null
|
|
223
297
|
}
|
|
224
298
|
return false
|
|
225
|
-
// return true
|
|
226
299
|
},
|
|
227
300
|
excludeDistrictResults: {
|
|
228
301
|
get() {
|
|
229
|
-
return !this.
|
|
302
|
+
return !this._includeDistrictResults
|
|
230
303
|
},
|
|
231
304
|
set(val) {
|
|
232
|
-
this.
|
|
233
|
-
}
|
|
305
|
+
this._includeDistrictResults = !val
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
// Enriched AI sources with host label
|
|
309
|
+
aiUiSources() {
|
|
310
|
+
return (this.aiSources || []).map(src => ({
|
|
311
|
+
...src,
|
|
312
|
+
hostLabel: this.labelFromUrl(src.url),
|
|
313
|
+
}))
|
|
234
314
|
},
|
|
235
315
|
},
|
|
236
316
|
|
|
237
317
|
watch: {
|
|
238
|
-
active
|
|
318
|
+
active(newVal) {
|
|
239
319
|
if (newVal) {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
320
|
+
// Focus keyword search by default for power users
|
|
321
|
+
if (this.$refs.search && this.$refs.search.$el) {
|
|
322
|
+
const input = this.$refs.search.$el.querySelector('input')
|
|
323
|
+
if (input) input.focus()
|
|
324
|
+
}
|
|
325
|
+
} else if (this.$refs.search && this.$refs.search.$el) {
|
|
326
|
+
const input = this.$refs.search.$el.querySelector('input')
|
|
327
|
+
if (input) input.blur()
|
|
243
328
|
}
|
|
244
329
|
},
|
|
245
|
-
|
|
330
|
+
|
|
331
|
+
// classic keyword search – unchanged behavior
|
|
332
|
+
keywords: debounce(function (newVal, oldVal) {
|
|
246
333
|
if (newVal !== oldVal) {
|
|
247
334
|
this.searchPages()
|
|
248
335
|
this.searchFiles()
|
|
249
336
|
this.searchGroups()
|
|
250
337
|
}
|
|
251
338
|
}, 500),
|
|
252
|
-
|
|
339
|
+
|
|
340
|
+
_includeDistrictResults() {
|
|
253
341
|
this.searchPages()
|
|
254
342
|
this.searchFiles()
|
|
255
343
|
},
|
|
344
|
+
|
|
345
|
+
// Clear AI answer if user clears the question
|
|
346
|
+
questionText(newVal) {
|
|
347
|
+
if (!newVal) {
|
|
348
|
+
this.aiAnswer = null
|
|
349
|
+
this.aiSources = []
|
|
350
|
+
}
|
|
351
|
+
},
|
|
256
352
|
},
|
|
257
353
|
|
|
258
354
|
methods: {
|
|
@@ -260,7 +356,6 @@ export default {
|
|
|
260
356
|
if (this.$store && this.$store.state.search) {
|
|
261
357
|
this.searchingPages = true
|
|
262
358
|
await this.$store.dispatch('search/queryPages', this.keywords)
|
|
263
|
-
// await this.$store.dispatch('search/setPages', this.keywords)
|
|
264
359
|
this.searchingPages = false
|
|
265
360
|
}
|
|
266
361
|
},
|
|
@@ -297,6 +392,81 @@ export default {
|
|
|
297
392
|
this.$emit('update:active', false)
|
|
298
393
|
}
|
|
299
394
|
},
|
|
395
|
+
|
|
396
|
+
// Small helper to derive a host label from URL
|
|
397
|
+
labelFromUrl(url) {
|
|
398
|
+
if (!url) return 'Academy District 20'
|
|
399
|
+
try {
|
|
400
|
+
const host = new URL(url).hostname
|
|
401
|
+
|
|
402
|
+
if (host === 'www.asd20.org') return 'Academy District 20'
|
|
403
|
+
|
|
404
|
+
if (host.endsWith('.asd20.org')) {
|
|
405
|
+
const subdomain = host.replace('.asd20.org', '')
|
|
406
|
+
switch (subdomain) {
|
|
407
|
+
case 'rampart':
|
|
408
|
+
return 'Rampart High School'
|
|
409
|
+
case 'pinecreek':
|
|
410
|
+
return 'Pine Creek High School'
|
|
411
|
+
// add more mappings as needed
|
|
412
|
+
default:
|
|
413
|
+
return subdomain.charAt(0).toUpperCase() + subdomain.slice(1)
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
return host
|
|
418
|
+
} catch {
|
|
419
|
+
return 'Academy District 20'
|
|
420
|
+
}
|
|
421
|
+
},
|
|
422
|
+
|
|
423
|
+
// Called when user clicks Ask or presses Enter in question field
|
|
424
|
+
onAskQuestion() {
|
|
425
|
+
const q = (this.questionText || '').trim()
|
|
426
|
+
if (!q) {
|
|
427
|
+
this.aiAnswer = null
|
|
428
|
+
this.aiSources = []
|
|
429
|
+
return
|
|
430
|
+
}
|
|
431
|
+
this.searchAi(q)
|
|
432
|
+
},
|
|
433
|
+
|
|
434
|
+
async searchAi(question) {
|
|
435
|
+
if (!question) return
|
|
436
|
+
if (this.searchingAi) return
|
|
437
|
+
|
|
438
|
+
this.searchingAi = true
|
|
439
|
+
try {
|
|
440
|
+
const organizationId =
|
|
441
|
+
this.organization && this.organization.id
|
|
442
|
+
? this.organization.id
|
|
443
|
+
: null
|
|
444
|
+
const organizationWebsite =
|
|
445
|
+
this.organization && this.organization.website
|
|
446
|
+
? this.organization.website
|
|
447
|
+
: null
|
|
448
|
+
|
|
449
|
+
const { answer, sources } = await this.$store.dispatch(
|
|
450
|
+
'search/queryAiSite',
|
|
451
|
+
{
|
|
452
|
+
question,
|
|
453
|
+
organizationId,
|
|
454
|
+
organizationWebsite,
|
|
455
|
+
includeDistrictResults: this._includeDistrictResults,
|
|
456
|
+
}
|
|
457
|
+
)
|
|
458
|
+
|
|
459
|
+
this.aiAnswer = answer
|
|
460
|
+
this.aiSources = sources || []
|
|
461
|
+
this.currentTab = 'Pages'
|
|
462
|
+
} catch (e) {
|
|
463
|
+
console.error('AI search failed', e)
|
|
464
|
+
this.aiAnswer = null
|
|
465
|
+
this.aiSources = []
|
|
466
|
+
} finally {
|
|
467
|
+
this.searchingAi = false
|
|
468
|
+
}
|
|
469
|
+
},
|
|
300
470
|
},
|
|
301
471
|
}
|
|
302
472
|
</script>
|
|
@@ -329,16 +499,99 @@ export default {
|
|
|
329
499
|
display: flex;
|
|
330
500
|
flex-direction: column;
|
|
331
501
|
flex-grow: 1;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
&__options {
|
|
505
|
+
padding: space(0.5);
|
|
506
|
+
display: flex;
|
|
507
|
+
flex-direction: column;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
&__field {
|
|
511
|
+
display: flex;
|
|
512
|
+
flex-direction: column;
|
|
513
|
+
flex: 1 1 auto;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
&__label {
|
|
517
|
+
font-size: 0.85rem;
|
|
518
|
+
font-weight: 600;
|
|
519
|
+
margin-bottom: space(0.25);
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
&__question-row {
|
|
523
|
+
display: flex;
|
|
524
|
+
align-items: stretch;
|
|
525
|
+
gap: space(0.5);
|
|
526
|
+
|
|
332
527
|
.asd20-search-field {
|
|
333
|
-
|
|
528
|
+
flex: 1 1 auto;
|
|
529
|
+
border-bottom: none;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
&__ask-button {
|
|
534
|
+
flex: 0 0 auto;
|
|
535
|
+
padding: 0 space(0.75);
|
|
536
|
+
border-radius: 999px;
|
|
537
|
+
border: 1px solid var(--color__primary, #22506a);
|
|
538
|
+
background: var(--color__primary, #22506a);
|
|
539
|
+
color: #fff;
|
|
540
|
+
font-weight: 600;
|
|
541
|
+
font-size: 0.9rem;
|
|
542
|
+
cursor: pointer;
|
|
543
|
+
white-space: nowrap;
|
|
544
|
+
|
|
545
|
+
&:disabled {
|
|
546
|
+
opacity: 0.5;
|
|
547
|
+
cursor: default;
|
|
334
548
|
}
|
|
335
549
|
}
|
|
550
|
+
|
|
336
551
|
&__results {
|
|
337
552
|
flex-grow: 1;
|
|
338
553
|
}
|
|
554
|
+
|
|
555
|
+
&__ai-result {
|
|
556
|
+
border-bottom: 1px solid var(--color__tertiary);
|
|
557
|
+
padding: space(0.75) space(0.75) space(0.5);
|
|
558
|
+
background: var(--website-page__alternate-background-t25);
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
&__ai-answer {
|
|
562
|
+
margin-bottom: space(0.5);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
&__ai-sources {
|
|
566
|
+
margin-top: space(0.25);
|
|
567
|
+
|
|
568
|
+
h4 {
|
|
569
|
+
font-size: 0.9rem;
|
|
570
|
+
font-weight: 600;
|
|
571
|
+
margin-bottom: space(0.25);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
ul {
|
|
575
|
+
list-style: none;
|
|
576
|
+
padding-left: 0;
|
|
577
|
+
margin: 0;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
li {
|
|
581
|
+
font-size: 0.85rem;
|
|
582
|
+
margin-bottom: space(0.25);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
&__ai-snippet {
|
|
587
|
+
margin: 0;
|
|
588
|
+
opacity: 0.85;
|
|
589
|
+
}
|
|
590
|
+
|
|
339
591
|
&__suggested {
|
|
340
592
|
border-top: 2px solid var(--color__tertiary);
|
|
341
593
|
background: var(--website-page__alternate-background-t50);
|
|
594
|
+
|
|
342
595
|
h3 {
|
|
343
596
|
font-size: 1rem;
|
|
344
597
|
font-weight: bold;
|
|
@@ -346,18 +599,21 @@ export default {
|
|
|
346
599
|
margin: space(0.25) 0 0 space(0.5);
|
|
347
600
|
}
|
|
348
601
|
}
|
|
602
|
+
|
|
349
603
|
::v-deep .asd20-checkbox {
|
|
350
604
|
justify-content: flex-start;
|
|
605
|
+
|
|
351
606
|
label {
|
|
352
607
|
padding: space(0.5) space(0.5) space(0.5) space(1.5);
|
|
353
608
|
flex-grow: 0;
|
|
354
609
|
}
|
|
355
610
|
}
|
|
356
611
|
}
|
|
612
|
+
|
|
357
613
|
@media (min-width: 768px) {
|
|
358
614
|
.asd20-site-search {
|
|
359
615
|
.asd20-notificaiton {
|
|
360
|
-
flex-direction:
|
|
616
|
+
flex-direction: row;
|
|
361
617
|
}
|
|
362
618
|
}
|
|
363
619
|
}
|
|
@@ -373,7 +629,7 @@ export default {
|
|
|
373
629
|
margin: 0;
|
|
374
630
|
list-style: none;
|
|
375
631
|
display: flex;
|
|
376
|
-
flex-direction:
|
|
632
|
+
flex-direction: row;
|
|
377
633
|
|
|
378
634
|
&::v-deep .asd20-modal {
|
|
379
635
|
margin-top: auto;
|
|
@@ -388,6 +644,7 @@ export default {
|
|
|
388
644
|
margin-left: space(0.5);
|
|
389
645
|
margin-right: space(-2.5);
|
|
390
646
|
}
|
|
647
|
+
|
|
391
648
|
input {
|
|
392
649
|
padding: 0 space(1) 0 space(2.75);
|
|
393
650
|
font-size: space(1);
|
|
@@ -397,7 +654,7 @@ export default {
|
|
|
397
654
|
|
|
398
655
|
.asd20-notification {
|
|
399
656
|
margin: space(1);
|
|
400
|
-
flex-direction:
|
|
657
|
+
flex-direction: row;
|
|
401
658
|
margin: space(0.5);
|
|
402
659
|
}
|
|
403
660
|
}
|
|
@@ -413,4 +670,4 @@ export default {
|
|
|
413
670
|
border-left: 1px solid var(--color__tertiary);
|
|
414
671
|
}
|
|
415
672
|
}
|
|
416
|
-
</style>
|
|
673
|
+
</style>
|
|
@@ -83,6 +83,8 @@
|
|
|
83
83
|
:stories="clubStories"
|
|
84
84
|
:stories-feed-props="storiesFeedProps"
|
|
85
85
|
@stories-in-view="$emit('stories-in-view')"
|
|
86
|
+
:organization="organization"
|
|
87
|
+
:organization-options="organizationOptions"
|
|
86
88
|
></asd20-feeds-section>
|
|
87
89
|
|
|
88
90
|
<intersect @enter="$emit('stories-in-view')">
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// helpers/search/queryAiSite.js
|
|
2
|
+
import axios from 'axios'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Calls Azure Function / API for AI site search.
|
|
6
|
+
* Expected response shape:
|
|
7
|
+
* {
|
|
8
|
+
* answer: string | null,
|
|
9
|
+
* sources: Array<{ url, title, snippet }>
|
|
10
|
+
* }
|
|
11
|
+
*/
|
|
12
|
+
export default async function queryAiSite({
|
|
13
|
+
question,
|
|
14
|
+
organizationId = null,
|
|
15
|
+
organizationWebsite = null,
|
|
16
|
+
includeDistrictResults = true,
|
|
17
|
+
}) {
|
|
18
|
+
const q = (question || '').trim()
|
|
19
|
+
if (!q) {
|
|
20
|
+
return { answer: null, sources: [] }
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const { data } = await axios.post(
|
|
24
|
+
process.env.AI_SITE_SEARCH_ENDPOINT, // e.g. https://...azurewebsites.net/api/httpAiSiteSearch
|
|
25
|
+
{
|
|
26
|
+
question: q,
|
|
27
|
+
organizationId,
|
|
28
|
+
organizationWebsite,
|
|
29
|
+
includeDistrictResults,
|
|
30
|
+
}
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
const rawSources = Array.isArray(data && data.sources) ? data.sources : []
|
|
34
|
+
|
|
35
|
+
const sources = rawSources.map((s) => ({
|
|
36
|
+
url: s.url,
|
|
37
|
+
title: s.title || s.url,
|
|
38
|
+
snippet: s.snippet || '',
|
|
39
|
+
}))
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
answer: data && data.answer ? data.answer : null,
|
|
43
|
+
sources,
|
|
44
|
+
}
|
|
45
|
+
}
|
package/src/store.js
CHANGED
|
@@ -36,10 +36,10 @@ const store = new Vuex.Store({
|
|
|
36
36
|
search: {
|
|
37
37
|
namespaced: true,
|
|
38
38
|
state: {
|
|
39
|
-
pages: [{one: '1'}],
|
|
40
|
-
files: [],
|
|
39
|
+
pages: [{ one: '1' }],
|
|
40
|
+
files: [],
|
|
41
41
|
groups: [],
|
|
42
|
-
|
|
42
|
+
includeDistrictResults: true,
|
|
43
43
|
languageCode: 'es',
|
|
44
44
|
isInLeadershipGroup: false,
|
|
45
45
|
},
|
|
@@ -52,10 +52,14 @@ const store = new Vuex.Store({
|
|
|
52
52
|
},
|
|
53
53
|
queryGroups() {
|
|
54
54
|
console.log('queried groups')
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
},
|
|
56
|
+
async queryAiSite(ctx, payload) {
|
|
57
|
+
// payload is { question, organizationId?, organizationWebsite?, includeDistrictResults? }
|
|
58
|
+
return await queryAiSiteHelper(payload)
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
},
|
|
59
63
|
})
|
|
60
64
|
|
|
61
65
|
export default store
|