@asd20/ui-next 2.10.11 → 2.11.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 +14 -0
- package/package.json +1 -1
- package/src/components/organisms/Asd20AiSearch/index.vue +28 -522
- package/src/components/organisms/Asd20SiteNavigation/index.vue +72 -0
- package/src/components/organisms/Asd20SiteSearch/index.vue +39 -111
- package/src/components/templates/Asd20DistrictVideoTemplate/index.vue +21 -0
- package/src/components/templates/Asd20SchoolHomeTemplate/index.vue +19 -0
- package/src/components/templates/Asd20SchoolHomeVideoTemplate/index.vue +21 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.11.1](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.11.0...ui-next-v2.11.1) (2026-05-26)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* remove search parameters from url ([b6bde4c](https://github.com/academydistrict20/asd20-ui-next/commit/b6bde4cb29ea762267ecd03f9739a47d8726ce1e))
|
|
9
|
+
|
|
10
|
+
# [2.11.0](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.10.11...ui-next-v2.11.0) (2026-05-26)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* allow ai search pill to pass search parameters to nav search; remove secondary ai search modal ([4bd6620](https://github.com/academydistrict20/asd20-ui-next/commit/4bd6620a72c75b26fdd6d9256152e35065e5c7d2))
|
|
16
|
+
|
|
3
17
|
## [2.10.11](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.10.10...ui-next-v2.10.11) (2026-05-20)
|
|
4
18
|
|
|
5
19
|
|
package/package.json
CHANGED
|
@@ -1,22 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
3
|
-
|
|
4
|
-
class="asd20-ai-search"
|
|
5
|
-
:class="{ 'asd20-ai-search--expanded': expanded }"
|
|
6
|
-
:style="rootStyle"
|
|
7
|
-
>
|
|
8
|
-
<div
|
|
9
|
-
class="asd20-ai-search__pill"
|
|
10
|
-
:class="{ 'asd20-ai-search__pill--hidden': expanded || isClosing }"
|
|
11
|
-
>
|
|
2
|
+
<div class="asd20-ai-search">
|
|
3
|
+
<div class="asd20-ai-search__pill">
|
|
12
4
|
<div class="asd20-ai-search__question-row">
|
|
13
5
|
<div class="asd20-ai-search__query">
|
|
14
6
|
<asd20-search-field
|
|
15
7
|
v-model="draftQuery"
|
|
16
8
|
id-tag="-ai-home"
|
|
17
9
|
:placeholder="placeholder"
|
|
18
|
-
@click="onPillInputInteraction"
|
|
19
|
-
@focusin="onPillInputInteraction"
|
|
20
10
|
@keyup.enter.stop.prevent="onSubmit"
|
|
21
11
|
/>
|
|
22
12
|
<button
|
|
@@ -39,81 +29,23 @@
|
|
|
39
29
|
size="md"
|
|
40
30
|
bordered
|
|
41
31
|
reversed
|
|
42
|
-
:disabled="!
|
|
32
|
+
:disabled="!hasDraftQuery"
|
|
43
33
|
@click.stop="onSubmit"
|
|
44
34
|
/>
|
|
45
35
|
</div>
|
|
46
36
|
</div>
|
|
47
|
-
|
|
48
|
-
<transition
|
|
49
|
-
name="ai-search-panel"
|
|
50
|
-
@before-leave="onBeforePanelLeave"
|
|
51
|
-
@after-leave="onAfterPanelLeave"
|
|
52
|
-
>
|
|
53
|
-
<div
|
|
54
|
-
v-show="expanded"
|
|
55
|
-
class="asd20-ai-search__panel"
|
|
56
|
-
>
|
|
57
|
-
<button
|
|
58
|
-
type="button"
|
|
59
|
-
class="asd20-ai-search__backdrop"
|
|
60
|
-
aria-label="Close AI search"
|
|
61
|
-
@click.stop="collapse"
|
|
62
|
-
/>
|
|
63
|
-
|
|
64
|
-
<button
|
|
65
|
-
type="button"
|
|
66
|
-
class="asd20-ai-search__close"
|
|
67
|
-
aria-label="Close AI search"
|
|
68
|
-
@click.stop="collapse"
|
|
69
|
-
>
|
|
70
|
-
<asd20-icon
|
|
71
|
-
name="close"
|
|
72
|
-
size="sm"
|
|
73
|
-
/>
|
|
74
|
-
</button>
|
|
75
|
-
|
|
76
|
-
<asd20-site-search
|
|
77
|
-
ref="siteSearch"
|
|
78
|
-
class="asd20-ai-search__site-search"
|
|
79
|
-
:active="expanded"
|
|
80
|
-
:inline="true"
|
|
81
|
-
:show-contacts="showContacts"
|
|
82
|
-
:pages="pages"
|
|
83
|
-
:files="files"
|
|
84
|
-
:groups="groups"
|
|
85
|
-
:include-district-results="includeDistrictResults"
|
|
86
|
-
:search-language-code="searchLanguageCode"
|
|
87
|
-
:query-pages-handler="queryPagesHandler"
|
|
88
|
-
:query-files-handler="queryFilesHandler"
|
|
89
|
-
:query-groups-handler="queryGroupsHandler"
|
|
90
|
-
:query-ai-site-handler="queryAiSiteHandler"
|
|
91
|
-
:organization="organization"
|
|
92
|
-
:organization-options="organizationOptions"
|
|
93
|
-
:ai-search-feedback-form-url="aiSearchFeedbackFormUrl"
|
|
94
|
-
@update:active="onSearchActiveUpdate"
|
|
95
|
-
/>
|
|
96
|
-
</div>
|
|
97
|
-
</transition>
|
|
98
37
|
</div>
|
|
99
38
|
</template>
|
|
100
39
|
|
|
101
40
|
<script>
|
|
102
41
|
import Asd20SearchField from '../../molecules/Asd20SearchField'
|
|
103
|
-
import Asd20SiteSearch from '../Asd20SiteSearch'
|
|
104
42
|
import Asd20Icon from '../../atoms/Asd20Icon'
|
|
105
43
|
import Asd20Button from '../../atoms/Asd20Button'
|
|
106
44
|
|
|
107
|
-
const SEARCH_SESSION_STORAGE_KEY = 'asd20-site-search-state-v1'
|
|
108
|
-
const SEARCH_STATE_SYNC_EVENT = 'asd20-site-search:state-sync'
|
|
109
|
-
const PHONE_MAX_WIDTH = 767
|
|
110
|
-
const PANEL_WIDTH_RATIO = 0.8
|
|
111
|
-
|
|
112
45
|
export default {
|
|
113
46
|
name: 'Asd20AiSearch',
|
|
114
47
|
components: {
|
|
115
48
|
Asd20SearchField,
|
|
116
|
-
Asd20SiteSearch,
|
|
117
49
|
Asd20Icon,
|
|
118
50
|
Asd20Button,
|
|
119
51
|
},
|
|
@@ -136,335 +68,26 @@ export default {
|
|
|
136
68
|
default: 'What can we help you find?',
|
|
137
69
|
},
|
|
138
70
|
},
|
|
71
|
+
emits: ['submit-search'],
|
|
139
72
|
data: () => ({
|
|
140
|
-
expanded: false,
|
|
141
73
|
draftQuery: '',
|
|
142
|
-
screenRightOffset: 0,
|
|
143
|
-
navLeftOffset: 0,
|
|
144
|
-
panelWidth: 0,
|
|
145
|
-
panelRightFromContainer: 0,
|
|
146
|
-
panelOriginX: 0,
|
|
147
|
-
panelOriginY: 0,
|
|
148
|
-
isClosing: false,
|
|
149
|
-
resumeStateAvailable: false,
|
|
150
74
|
}),
|
|
151
75
|
computed: {
|
|
152
|
-
rootStyle() {
|
|
153
|
-
return {
|
|
154
|
-
'--asd20-ai-search-screen-right-offset': `${this.screenRightOffset}px`,
|
|
155
|
-
'--asd20-ai-search-nav-left-offset': `${this.navLeftOffset}px`,
|
|
156
|
-
'--asd20-ai-search-panel-width': `${this.panelWidth}px`,
|
|
157
|
-
'--asd20-ai-search-panel-right-from-container': `${this.panelRightFromContainer}px`,
|
|
158
|
-
'--asd20-ai-search-origin-x': `${this.panelOriginX}px`,
|
|
159
|
-
'--asd20-ai-search-origin-y': `${this.panelOriginY}px`,
|
|
160
|
-
}
|
|
161
|
-
},
|
|
162
|
-
|
|
163
76
|
hasDraftQuery() {
|
|
164
77
|
return !!(this.draftQuery || '').trim()
|
|
165
78
|
},
|
|
166
|
-
|
|
167
|
-
canSubmitOrResume() {
|
|
168
|
-
return this.hasDraftQuery || this.resumeStateAvailable
|
|
169
|
-
},
|
|
170
|
-
},
|
|
171
|
-
mounted() {
|
|
172
|
-
this.updatePanelLayout()
|
|
173
|
-
this.updatePanelOrigin()
|
|
174
|
-
this.updateResumeStateAvailability()
|
|
175
|
-
if (typeof document !== 'undefined') {
|
|
176
|
-
document.addEventListener('mousedown', this.onDocumentPointerDown)
|
|
177
|
-
document.addEventListener('touchstart', this.onDocumentPointerDown, {
|
|
178
|
-
passive: true,
|
|
179
|
-
})
|
|
180
|
-
}
|
|
181
|
-
if (typeof window !== 'undefined') {
|
|
182
|
-
window.addEventListener('resize', this.onWindowResize, { passive: true })
|
|
183
|
-
window.addEventListener('orientationchange', this.onWindowResize, {
|
|
184
|
-
passive: true,
|
|
185
|
-
})
|
|
186
|
-
window.addEventListener(SEARCH_STATE_SYNC_EVENT, this.onSearchStateSync)
|
|
187
|
-
window.addEventListener('focus', this.onWindowFocus, { passive: true })
|
|
188
|
-
}
|
|
189
|
-
},
|
|
190
|
-
beforeUnmount() {
|
|
191
|
-
this.teardownWindowBindings()
|
|
192
79
|
},
|
|
193
80
|
methods: {
|
|
194
|
-
teardownWindowBindings() {
|
|
195
|
-
if (typeof document !== 'undefined') {
|
|
196
|
-
document.removeEventListener('mousedown', this.onDocumentPointerDown)
|
|
197
|
-
document.removeEventListener('touchstart', this.onDocumentPointerDown)
|
|
198
|
-
}
|
|
199
|
-
if (typeof window !== 'undefined') {
|
|
200
|
-
window.removeEventListener('resize', this.onWindowResize)
|
|
201
|
-
window.removeEventListener('orientationchange', this.onWindowResize)
|
|
202
|
-
window.removeEventListener(
|
|
203
|
-
SEARCH_STATE_SYNC_EVENT,
|
|
204
|
-
this.onSearchStateSync
|
|
205
|
-
)
|
|
206
|
-
window.removeEventListener('focus', this.onWindowFocus)
|
|
207
|
-
}
|
|
208
|
-
},
|
|
209
|
-
onWindowResize() {
|
|
210
|
-
if (typeof window !== 'undefined' && window.innerWidth < 1024) {
|
|
211
|
-
this.collapse()
|
|
212
|
-
}
|
|
213
|
-
this.updatePanelLayout()
|
|
214
|
-
if (!this.expanded) {
|
|
215
|
-
this.updatePanelOrigin()
|
|
216
|
-
}
|
|
217
|
-
},
|
|
218
|
-
|
|
219
|
-
updateScreenRightOffset() {
|
|
220
|
-
if (typeof window === 'undefined') return
|
|
221
|
-
if (!this.$refs.container || !this.$refs.container.getBoundingClientRect)
|
|
222
|
-
return
|
|
223
|
-
const rect = this.$refs.container.getBoundingClientRect()
|
|
224
|
-
this.screenRightOffset = Math.max(0, window.innerWidth - rect.right)
|
|
225
|
-
},
|
|
226
|
-
|
|
227
|
-
updateNavLeftOffset() {
|
|
228
|
-
if (typeof window === 'undefined' || typeof document === 'undefined') {
|
|
229
|
-
return
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
if (window.innerWidth < 1024) {
|
|
233
|
-
this.navLeftOffset = 0
|
|
234
|
-
return
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
const nav = document.getElementById('site-navigation')
|
|
238
|
-
if (!nav || !nav.getBoundingClientRect) {
|
|
239
|
-
this.navLeftOffset = 0
|
|
240
|
-
return
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
const rect = nav.getBoundingClientRect()
|
|
244
|
-
const rightEdge = Math.max(0, rect.right || 0)
|
|
245
|
-
this.navLeftOffset =
|
|
246
|
-
rightEdge > 0 && rightEdge < window.innerWidth * 0.5 ? rightEdge : 0
|
|
247
|
-
},
|
|
248
|
-
|
|
249
|
-
panelLayoutForViewport(containerRect) {
|
|
250
|
-
if (!containerRect || typeof window === 'undefined') {
|
|
251
|
-
return { width: 0, rightFromContainer: 0 }
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
const viewportWidth = window.innerWidth
|
|
255
|
-
const rightOffset = Math.max(0, window.innerWidth - containerRect.right)
|
|
256
|
-
|
|
257
|
-
if (viewportWidth <= PHONE_MAX_WIDTH) {
|
|
258
|
-
return {
|
|
259
|
-
width: viewportWidth,
|
|
260
|
-
rightFromContainer: -rightOffset,
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
const navRightEdge =
|
|
265
|
-
viewportWidth >= 1024 ? Math.max(0, this.navLeftOffset) : 0
|
|
266
|
-
const maxAvailableWidth = Math.max(0, viewportWidth - navRightEdge)
|
|
267
|
-
const targetWidth = viewportWidth * PANEL_WIDTH_RATIO
|
|
268
|
-
const width = Math.max(0, Math.min(targetWidth, maxAvailableWidth))
|
|
269
|
-
const desiredViewportRightGap = Math.max(
|
|
270
|
-
0,
|
|
271
|
-
(viewportWidth - navRightEdge - width) / 2
|
|
272
|
-
)
|
|
273
|
-
|
|
274
|
-
return {
|
|
275
|
-
width,
|
|
276
|
-
rightFromContainer: desiredViewportRightGap - rightOffset,
|
|
277
|
-
}
|
|
278
|
-
},
|
|
279
|
-
|
|
280
|
-
updatePanelLayout() {
|
|
281
|
-
this.updateScreenRightOffset()
|
|
282
|
-
this.updateNavLeftOffset()
|
|
283
|
-
if (!this.$refs.container || !this.$refs.container.getBoundingClientRect) {
|
|
284
|
-
return
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
const rect = this.$refs.container.getBoundingClientRect()
|
|
288
|
-
const { width, rightFromContainer } = this.panelLayoutForViewport(rect)
|
|
289
|
-
this.panelWidth = width
|
|
290
|
-
this.panelRightFromContainer = rightFromContainer
|
|
291
|
-
},
|
|
292
|
-
|
|
293
|
-
updatePanelOrigin() {
|
|
294
|
-
if (typeof window === 'undefined') return
|
|
295
|
-
if (!this.$refs.container || !this.$refs.container.getBoundingClientRect) {
|
|
296
|
-
return
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
const goButton = this.$el.querySelector('.asd20-ai-search__go-button')
|
|
300
|
-
if (!goButton || !goButton.getBoundingClientRect) return
|
|
301
|
-
|
|
302
|
-
const containerRect = this.$refs.container.getBoundingClientRect()
|
|
303
|
-
const goRect = goButton.getBoundingClientRect()
|
|
304
|
-
const { width, rightFromContainer } =
|
|
305
|
-
this.panelLayoutForViewport(containerRect)
|
|
306
|
-
const panelWidth = width
|
|
307
|
-
const panelLeft =
|
|
308
|
-
containerRect.right - rightFromContainer - panelWidth
|
|
309
|
-
|
|
310
|
-
const originX = goRect.left + goRect.width / 2 - panelLeft
|
|
311
|
-
const originY = goRect.top + goRect.height / 2 - containerRect.top
|
|
312
|
-
|
|
313
|
-
this.panelOriginX = Math.max(0, Math.min(panelWidth, originX))
|
|
314
|
-
this.panelOriginY = Math.max(0, originY)
|
|
315
|
-
},
|
|
316
|
-
|
|
317
|
-
onDocumentPointerDown(event) {
|
|
318
|
-
if (!this.expanded) return
|
|
319
|
-
if (!this.$refs.container) return
|
|
320
|
-
if (!this.$refs.container.contains(event.target)) {
|
|
321
|
-
this.collapse()
|
|
322
|
-
}
|
|
323
|
-
},
|
|
324
|
-
|
|
325
81
|
onSubmit() {
|
|
326
82
|
const text = (this.draftQuery || '').trim()
|
|
327
|
-
|
|
328
|
-
},
|
|
329
|
-
|
|
330
|
-
onWindowFocus() {
|
|
331
|
-
this.updateResumeStateAvailability()
|
|
332
|
-
},
|
|
333
|
-
|
|
334
|
-
onSearchStateSync() {
|
|
335
|
-
this.updateResumeStateAvailability()
|
|
336
|
-
},
|
|
337
|
-
|
|
338
|
-
getSearchSessionStorage() {
|
|
339
|
-
if (typeof window === 'undefined' || !window.sessionStorage) return null
|
|
340
|
-
try {
|
|
341
|
-
return window.sessionStorage
|
|
342
|
-
} catch (error) {
|
|
343
|
-
return null
|
|
344
|
-
}
|
|
345
|
-
},
|
|
346
|
-
|
|
347
|
-
hasPersistedSearchState() {
|
|
348
|
-
const storage = this.getSearchSessionStorage()
|
|
349
|
-
if (!storage) return false
|
|
350
|
-
|
|
351
|
-
try {
|
|
352
|
-
const raw = storage.getItem(SEARCH_SESSION_STORAGE_KEY)
|
|
353
|
-
if (!raw) return false
|
|
354
|
-
const parsed = JSON.parse(raw)
|
|
355
|
-
if (!parsed || typeof parsed !== 'object') return false
|
|
356
|
-
const state = parsed.state && typeof parsed.state === 'object'
|
|
357
|
-
? parsed.state
|
|
358
|
-
: parsed
|
|
359
|
-
const text = typeof state.text === 'string' ? state.text.trim() : ''
|
|
360
|
-
return !!text
|
|
361
|
-
} catch (error) {
|
|
362
|
-
return false
|
|
363
|
-
}
|
|
364
|
-
},
|
|
365
|
-
|
|
366
|
-
hasExistingConversation() {
|
|
367
|
-
const siteSearch = this.$refs.siteSearch
|
|
368
|
-
if (!siteSearch) return false
|
|
369
|
-
if (Array.isArray(siteSearch.aiTranscript) && siteSearch.aiTranscript.length) {
|
|
370
|
-
return true
|
|
371
|
-
}
|
|
372
|
-
return !!siteSearch.hasAssistantTurns
|
|
373
|
-
},
|
|
374
|
-
|
|
375
|
-
hasExistingResults() {
|
|
376
|
-
const siteSearch = this.$refs.siteSearch
|
|
377
|
-
if (!siteSearch) return false
|
|
378
|
-
const pages = Array.isArray(siteSearch.currentPages)
|
|
379
|
-
? siteSearch.currentPages
|
|
380
|
-
: siteSearch.resolvedPages
|
|
381
|
-
const files = Array.isArray(siteSearch.currentFiles)
|
|
382
|
-
? siteSearch.currentFiles
|
|
383
|
-
: siteSearch.resolvedFiles
|
|
384
|
-
const groups = Array.isArray(siteSearch.currentGroups)
|
|
385
|
-
? siteSearch.currentGroups
|
|
386
|
-
: siteSearch.resolvedGroups
|
|
387
|
-
if (
|
|
388
|
-
Array.isArray(pages) &&
|
|
389
|
-
pages.length
|
|
390
|
-
) {
|
|
391
|
-
return true
|
|
392
|
-
}
|
|
393
|
-
if (
|
|
394
|
-
Array.isArray(files) &&
|
|
395
|
-
files.length
|
|
396
|
-
) {
|
|
397
|
-
return true
|
|
398
|
-
}
|
|
399
|
-
if (
|
|
400
|
-
Array.isArray(groups) &&
|
|
401
|
-
groups.length
|
|
402
|
-
) {
|
|
403
|
-
return true
|
|
404
|
-
}
|
|
405
|
-
return false
|
|
406
|
-
},
|
|
407
|
-
|
|
408
|
-
hasResumeState() {
|
|
409
|
-
return (
|
|
410
|
-
this.hasExistingConversation() ||
|
|
411
|
-
this.hasExistingResults() ||
|
|
412
|
-
this.hasPersistedSearchState()
|
|
413
|
-
)
|
|
414
|
-
},
|
|
415
|
-
|
|
416
|
-
updateResumeStateAvailability() {
|
|
417
|
-
this.resumeStateAvailable = this.hasResumeState()
|
|
418
|
-
},
|
|
419
|
-
|
|
420
|
-
onPillInputInteraction() {
|
|
421
|
-
if (this.expanded || this.isClosing) return
|
|
422
|
-
this.updateResumeStateAvailability()
|
|
423
|
-
if (!this.hasResumeState()) return
|
|
424
|
-
this.expand({ submit: false })
|
|
425
|
-
},
|
|
426
|
-
|
|
427
|
-
onSearchActiveUpdate(val) {
|
|
428
|
-
if (!val) this.collapse()
|
|
429
|
-
},
|
|
430
|
-
|
|
431
|
-
collapse() {
|
|
432
|
-
if (!this.expanded) return
|
|
433
|
-
this.expanded = false
|
|
434
|
-
this.draftQuery = ''
|
|
435
|
-
this.updateResumeStateAvailability()
|
|
436
|
-
},
|
|
437
|
-
|
|
438
|
-
onBeforePanelLeave() {
|
|
439
|
-
this.isClosing = true
|
|
440
|
-
},
|
|
441
|
-
|
|
442
|
-
onAfterPanelLeave() {
|
|
443
|
-
this.isClosing = false
|
|
444
|
-
},
|
|
445
|
-
|
|
446
|
-
expand(options = {}) {
|
|
447
|
-
const shouldSubmit = !!options.submit
|
|
448
|
-
this.isClosing = false
|
|
449
|
-
this.updatePanelLayout()
|
|
450
|
-
this.updatePanelOrigin()
|
|
451
|
-
this.expanded = true
|
|
83
|
+
if (!text) return
|
|
452
84
|
|
|
453
|
-
this.$
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
const text = this.draftQuery
|
|
458
|
-
if (typeof siteSearch.applyInputText === 'function') {
|
|
459
|
-
siteSearch.applyInputText(text, { submit: shouldSubmit })
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
if (shouldSubmit) {
|
|
463
|
-
this.draftQuery = ''
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
this.updateResumeStateAvailability()
|
|
85
|
+
this.$emit('submit-search', {
|
|
86
|
+
text,
|
|
87
|
+
submit: true,
|
|
88
|
+
requestedAt: Date.now(),
|
|
467
89
|
})
|
|
90
|
+
this.draftQuery = ''
|
|
468
91
|
},
|
|
469
92
|
},
|
|
470
93
|
}
|
|
@@ -526,16 +149,23 @@ export default {
|
|
|
526
149
|
}
|
|
527
150
|
}
|
|
528
151
|
|
|
529
|
-
&__pill--hidden {
|
|
530
|
-
opacity: 0;
|
|
531
|
-
visibility: hidden;
|
|
532
|
-
pointer-events: none;
|
|
533
|
-
}
|
|
534
|
-
|
|
535
152
|
&__pill:focus-within {
|
|
536
153
|
box-shadow: 0 0 0 2px var(--color__accent-t70);
|
|
537
154
|
}
|
|
538
155
|
|
|
156
|
+
&__question-row {
|
|
157
|
+
display: flex;
|
|
158
|
+
align-items: center;
|
|
159
|
+
width: 100%;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
&__query {
|
|
163
|
+
position: relative;
|
|
164
|
+
flex: 1 1 auto;
|
|
165
|
+
min-width: 0;
|
|
166
|
+
padding-left: 0.5rem;
|
|
167
|
+
}
|
|
168
|
+
|
|
539
169
|
&__icon-button {
|
|
540
170
|
position: absolute;
|
|
541
171
|
top: 50%;
|
|
@@ -552,19 +182,6 @@ export default {
|
|
|
552
182
|
color: var(--color__primary-t50);
|
|
553
183
|
}
|
|
554
184
|
|
|
555
|
-
&__question-row {
|
|
556
|
-
display: flex;
|
|
557
|
-
align-items: center;
|
|
558
|
-
width: 100%;
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
&__query {
|
|
562
|
-
position: relative;
|
|
563
|
-
flex: 1 1 auto;
|
|
564
|
-
min-width: 0;
|
|
565
|
-
padding-left: 0.5rem;
|
|
566
|
-
}
|
|
567
|
-
|
|
568
185
|
&__go-button {
|
|
569
186
|
flex: 0 0 auto;
|
|
570
187
|
border-radius: 3rem;
|
|
@@ -584,133 +201,22 @@ export default {
|
|
|
584
201
|
line-height: 1;
|
|
585
202
|
}
|
|
586
203
|
|
|
587
|
-
&__icon-button:focus
|
|
588
|
-
&__close:focus {
|
|
204
|
+
&__icon-button:focus {
|
|
589
205
|
outline: none;
|
|
590
206
|
box-shadow: 0 0 0 2px var(--color__accent-t70);
|
|
591
207
|
border-radius: 999px;
|
|
592
208
|
}
|
|
593
|
-
|
|
594
|
-
&__panel {
|
|
595
|
-
position: absolute;
|
|
596
|
-
top: 0;
|
|
597
|
-
left: 0;
|
|
598
|
-
right: 0;
|
|
599
|
-
z-index: 8;
|
|
600
|
-
min-height: 75vh;
|
|
601
|
-
height: 75vh;
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
&__backdrop {
|
|
605
|
-
position: fixed;
|
|
606
|
-
inset: 0;
|
|
607
|
-
border: 0;
|
|
608
|
-
margin: 0;
|
|
609
|
-
padding: 0;
|
|
610
|
-
background: var(--color__primary);
|
|
611
|
-
opacity: 0.45;
|
|
612
|
-
z-index: 7;
|
|
613
|
-
cursor: pointer;
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
&__site-search {
|
|
617
|
-
position: relative;
|
|
618
|
-
z-index: 8;
|
|
619
|
-
height: 100%;
|
|
620
|
-
|
|
621
|
-
:deep(.asd20-site-search__ai-disclaimer-text) {
|
|
622
|
-
padding-right: 3rem;
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
&__close {
|
|
627
|
-
position: absolute;
|
|
628
|
-
top: space(0.625);
|
|
629
|
-
right: space(0.625);
|
|
630
|
-
z-index: 9;
|
|
631
|
-
width: 1.75rem;
|
|
632
|
-
height: 1.75rem;
|
|
633
|
-
border-radius: 999px;
|
|
634
|
-
border: 1px solid var(--color__tertiary);
|
|
635
|
-
background: transparent;
|
|
636
|
-
cursor: pointer;
|
|
637
|
-
display: inline-flex;
|
|
638
|
-
align-items: center;
|
|
639
|
-
justify-content: center;
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
.ai-search-panel-enter-active {
|
|
644
|
-
transition: opacity 380ms ease;
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
.ai-search-panel-leave-active {
|
|
648
|
-
transition: opacity 440ms ease;
|
|
649
209
|
}
|
|
650
210
|
|
|
651
|
-
|
|
652
|
-
.ai-search-panel-enter-from,
|
|
653
|
-
.ai-search-panel-leave-to {
|
|
654
|
-
opacity: 0;
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
.ai-search-panel-enter-active .asd20-ai-search__site-search,
|
|
658
|
-
.ai-search-panel-enter-active .asd20-ai-search__close {
|
|
659
|
-
transition:
|
|
660
|
-
transform 520ms cubic-bezier(0.22, 0.8, 0.22, 1),
|
|
661
|
-
opacity 380ms ease;
|
|
662
|
-
transform-origin: var(--asd20-ai-search-origin-x, calc(100% - 2.5rem))
|
|
663
|
-
var(--asd20-ai-search-origin-y, 1.375rem);
|
|
664
|
-
will-change: transform, opacity;
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
.ai-search-panel-leave-active .asd20-ai-search__site-search,
|
|
668
|
-
.ai-search-panel-leave-active .asd20-ai-search__close {
|
|
669
|
-
transition:
|
|
670
|
-
transform 460ms cubic-bezier(0.4, 0, 1, 1),
|
|
671
|
-
opacity 440ms ease;
|
|
672
|
-
transform-origin: var(--asd20-ai-search-origin-x, calc(100% - 2.5rem))
|
|
673
|
-
var(--asd20-ai-search-origin-y, 1.375rem);
|
|
674
|
-
will-change: transform, opacity;
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
.ai-search-panel-enter .asd20-ai-search__site-search,
|
|
678
|
-
.ai-search-panel-enter-from .asd20-ai-search__site-search,
|
|
679
|
-
.ai-search-panel-leave-to .asd20-ai-search__site-search,
|
|
680
|
-
.ai-search-panel-enter .asd20-ai-search__close,
|
|
681
|
-
.ai-search-panel-enter-from .asd20-ai-search__close,
|
|
682
|
-
.ai-search-panel-leave-to .asd20-ai-search__close {
|
|
683
|
-
transform: scale3d(0.16, 0.1, 1);
|
|
684
|
-
opacity: 0;
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
.ai-search-panel-enter-active .asd20-ai-search__backdrop,
|
|
688
|
-
.ai-search-panel-leave-active .asd20-ai-search__backdrop {
|
|
689
|
-
transition: opacity 440ms ease;
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
.ai-search-panel-enter .asd20-ai-search__backdrop,
|
|
693
|
-
.ai-search-panel-enter-from .asd20-ai-search__backdrop,
|
|
694
|
-
.ai-search-panel-leave-to .asd20-ai-search__backdrop {
|
|
695
|
-
opacity: 0;
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
@media (max-width: 1023px) {
|
|
211
|
+
@media (max-width: 479px) {
|
|
699
212
|
.asd20-ai-search {
|
|
700
|
-
|
|
213
|
+
min-width: 0;
|
|
701
214
|
}
|
|
702
215
|
}
|
|
703
216
|
|
|
704
|
-
@media (
|
|
217
|
+
@media (max-width: 1023px) {
|
|
705
218
|
.asd20-ai-search {
|
|
706
|
-
|
|
707
|
-
width: var(
|
|
708
|
-
--asd20-ai-search-panel-width,
|
|
709
|
-
calc(100vw - (2 * var(--asd20-ai-search-screen-right-offset, 0px)))
|
|
710
|
-
);
|
|
711
|
-
left: auto;
|
|
712
|
-
right: var(--asd20-ai-search-panel-right-from-container, 0px);
|
|
713
|
-
}
|
|
219
|
+
display: none;
|
|
714
220
|
}
|
|
715
221
|
}
|
|
716
222
|
</style>
|
|
@@ -65,9 +65,21 @@
|
|
|
65
65
|
<transition name="slide">
|
|
66
66
|
<asd20-site-search
|
|
67
67
|
v-show="searchOpen"
|
|
68
|
+
ref="siteSearch"
|
|
68
69
|
:active="searchOpen"
|
|
70
|
+
:show-contacts="showContacts"
|
|
71
|
+
:pages="pages"
|
|
72
|
+
:files="files"
|
|
73
|
+
:groups="groups"
|
|
74
|
+
:include-district-results="includeDistrictResults"
|
|
75
|
+
:search-language-code="searchLanguageCode"
|
|
76
|
+
:query-pages-handler="queryPagesHandler"
|
|
77
|
+
:query-files-handler="queryFilesHandler"
|
|
78
|
+
:query-groups-handler="queryGroupsHandler"
|
|
79
|
+
:query-ai-site-handler="queryAiSiteHandler"
|
|
69
80
|
:organization="organization"
|
|
70
81
|
:organization-options="organizationOptions"
|
|
82
|
+
:ai-search-feedback-form-url="aiSearchFeedbackFormUrl"
|
|
71
83
|
@update:active="$emit('update:searchOpen', $event)"
|
|
72
84
|
>
|
|
73
85
|
</asd20-site-search>
|
|
@@ -102,14 +114,27 @@ export default {
|
|
|
102
114
|
condensed: { type: Boolean, default: false },
|
|
103
115
|
menuOpen: { type: Boolean, default: false },
|
|
104
116
|
searchOpen: { type: Boolean, default: false },
|
|
117
|
+
searchRequest: { type: Object, default: null },
|
|
118
|
+
pages: { type: Array, default: () => [] },
|
|
119
|
+
files: { type: Array, default: () => [] },
|
|
120
|
+
groups: { type: Array, default: () => [] },
|
|
121
|
+
showContacts: { type: Boolean, default: true },
|
|
122
|
+
includeDistrictResults: { type: Boolean, default: true },
|
|
123
|
+
searchLanguageCode: { type: String, default: null },
|
|
124
|
+
queryPagesHandler: { type: Function, default: null },
|
|
125
|
+
queryFilesHandler: { type: Function, default: null },
|
|
126
|
+
queryGroupsHandler: { type: Function, default: null },
|
|
127
|
+
queryAiSiteHandler: { type: Function, default: null },
|
|
105
128
|
organization: { type: Object, default: null },
|
|
106
129
|
organizationOptions: { type: Array, default: () => [] },
|
|
130
|
+
aiSearchFeedbackFormUrl: { type: String, default: '' },
|
|
107
131
|
},
|
|
108
132
|
data: () => ({
|
|
109
133
|
keyboardTriggeredLastAction: false,
|
|
110
134
|
desktop: false,
|
|
111
135
|
isLoaded: false,
|
|
112
136
|
zoomed: false,
|
|
137
|
+
pendingSearchRequest: null,
|
|
113
138
|
}),
|
|
114
139
|
computed: {
|
|
115
140
|
emptyNav() {
|
|
@@ -124,6 +149,14 @@ export default {
|
|
|
124
149
|
}
|
|
125
150
|
})
|
|
126
151
|
},
|
|
152
|
+
searchOpen: function (val) {
|
|
153
|
+
if (val) {
|
|
154
|
+
this.$nextTick(() => this.applyPendingSearchRequest())
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
searchRequest: function (request) {
|
|
158
|
+
this.queueSearchRequest(request)
|
|
159
|
+
},
|
|
127
160
|
},
|
|
128
161
|
mounted() {
|
|
129
162
|
this.desktop = window.innerWidth >= 1024
|
|
@@ -153,6 +186,45 @@ export default {
|
|
|
153
186
|
this.desktop = window.innerWidth >= 1024
|
|
154
187
|
this.zoomed = window.innerHeight <= 650
|
|
155
188
|
},
|
|
189
|
+
normalizeSearchRequest(request) {
|
|
190
|
+
if (!request || typeof request !== 'object') return null
|
|
191
|
+
const text = typeof request.text === 'string' ? request.text.trim() : ''
|
|
192
|
+
if (!text) return null
|
|
193
|
+
|
|
194
|
+
return {
|
|
195
|
+
text,
|
|
196
|
+
submit: request.submit !== false,
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
queueSearchRequest(request) {
|
|
200
|
+
const nextRequest = this.normalizeSearchRequest(request)
|
|
201
|
+
if (!nextRequest) return
|
|
202
|
+
|
|
203
|
+
this.pendingSearchRequest = nextRequest
|
|
204
|
+
const siteSearch = this.$refs.siteSearch
|
|
205
|
+
if (typeof siteSearch?.prepareProgrammaticInput === 'function') {
|
|
206
|
+
siteSearch.prepareProgrammaticInput()
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (this.menuOpen) {
|
|
210
|
+
this.$emit('update:menuOpen', false)
|
|
211
|
+
}
|
|
212
|
+
if (!this.searchOpen) {
|
|
213
|
+
this.$emit('update:searchOpen', true)
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
this.$nextTick(() => this.applyPendingSearchRequest())
|
|
217
|
+
},
|
|
218
|
+
applyPendingSearchRequest() {
|
|
219
|
+
if (!this.searchOpen || !this.pendingSearchRequest) return
|
|
220
|
+
|
|
221
|
+
const siteSearch = this.$refs.siteSearch
|
|
222
|
+
if (typeof siteSearch?.applyInputText !== 'function') return
|
|
223
|
+
|
|
224
|
+
const request = this.pendingSearchRequest
|
|
225
|
+
this.pendingSearchRequest = null
|
|
226
|
+
siteSearch.applyInputText(request.text, { submit: request.submit })
|
|
227
|
+
},
|
|
156
228
|
toggleSearch() {
|
|
157
229
|
this.$emit('update:searchOpen', !this.searchOpen)
|
|
158
230
|
},
|
|
@@ -683,7 +683,6 @@ export default {
|
|
|
683
683
|
searchMode: '',
|
|
684
684
|
routeRestoreInProgress: false,
|
|
685
685
|
lastRestoredSearchKey: '',
|
|
686
|
-
skipNextRouteRestore: false,
|
|
687
686
|
suppressAutoRestore: false,
|
|
688
687
|
lastManualTabChangeAt: 0,
|
|
689
688
|
lastManualTabLabel: '',
|
|
@@ -1077,9 +1076,9 @@ export default {
|
|
|
1077
1076
|
this.focusQuery()
|
|
1078
1077
|
this.refreshResultsScrollLayer()
|
|
1079
1078
|
})
|
|
1080
|
-
this.
|
|
1079
|
+
this.restoreSearchState()
|
|
1081
1080
|
} else {
|
|
1082
|
-
this.
|
|
1081
|
+
this.clearLegacySearchRouteQuery()
|
|
1083
1082
|
if (!this.inline) this.unlockBodyScroll()
|
|
1084
1083
|
this.blurQuery()
|
|
1085
1084
|
}
|
|
@@ -1090,7 +1089,7 @@ export default {
|
|
|
1090
1089
|
if (newVal === 'Answers') {
|
|
1091
1090
|
this.$nextTick(() => this.refreshResultsScrollLayer())
|
|
1092
1091
|
}
|
|
1093
|
-
this.
|
|
1092
|
+
this.syncSearchState({ tab: newVal })
|
|
1094
1093
|
},
|
|
1095
1094
|
|
|
1096
1095
|
aiAnswer() {
|
|
@@ -1115,7 +1114,7 @@ export default {
|
|
|
1115
1114
|
this.selectedGroup = null
|
|
1116
1115
|
this.searchPages({ runId })
|
|
1117
1116
|
this.searchFilesWithGroupOwners({ runId })
|
|
1118
|
-
this.
|
|
1117
|
+
this.syncSearchState()
|
|
1119
1118
|
}
|
|
1120
1119
|
}, 400),
|
|
1121
1120
|
|
|
@@ -1124,7 +1123,7 @@ export default {
|
|
|
1124
1123
|
const runId = this.beginSearchRun()
|
|
1125
1124
|
this.searchPages({ runId })
|
|
1126
1125
|
this.searchFilesWithGroupOwners({ runId })
|
|
1127
|
-
this.
|
|
1126
|
+
this.syncSearchState()
|
|
1128
1127
|
},
|
|
1129
1128
|
// Clear AI answer if user clears the input
|
|
1130
1129
|
|
|
@@ -1137,34 +1136,20 @@ export default {
|
|
|
1137
1136
|
this.aiKeywordsDisplayPages = ''
|
|
1138
1137
|
}
|
|
1139
1138
|
},
|
|
1140
|
-
|
|
1141
|
-
'$route.query': {
|
|
1142
|
-
handler() {
|
|
1143
|
-
if (this.suppressAutoRestore) return
|
|
1144
|
-
if (this.searchingAi) return
|
|
1145
|
-
if (this.hasRecentManualTabSelection()) return
|
|
1146
|
-
if (this.skipNextRouteRestore) {
|
|
1147
|
-
this.skipNextRouteRestore = false
|
|
1148
|
-
return
|
|
1149
|
-
}
|
|
1150
|
-
if (!this.getRouteSearchState(this.$route.query)) {
|
|
1151
|
-
this.lastRestoredSearchKey = ''
|
|
1152
|
-
}
|
|
1153
|
-
if (this.active) this.restoreSearchStateFromRoute()
|
|
1154
|
-
},
|
|
1155
|
-
},
|
|
1156
1139
|
},
|
|
1157
1140
|
|
|
1158
1141
|
mounted() {
|
|
1159
1142
|
if (this.active && !this.inline) {
|
|
1160
1143
|
this.lockBodyScroll()
|
|
1161
1144
|
}
|
|
1162
|
-
|
|
1145
|
+
const didReload = this.didPageReload()
|
|
1146
|
+
if (didReload) {
|
|
1163
1147
|
this.persistSearchState(null)
|
|
1164
1148
|
this.lastRestoredSearchKey = ''
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1149
|
+
}
|
|
1150
|
+
this.clearLegacySearchRouteQuery()
|
|
1151
|
+
if (!didReload && this.active) {
|
|
1152
|
+
this.restoreSearchState()
|
|
1168
1153
|
}
|
|
1169
1154
|
if (typeof window !== 'undefined') {
|
|
1170
1155
|
window.addEventListener('resize', this.onWindowReflow, { passive: true })
|
|
@@ -1323,11 +1308,6 @@ export default {
|
|
|
1323
1308
|
}
|
|
1324
1309
|
},
|
|
1325
1310
|
|
|
1326
|
-
normalizeRouteQueryValue(value) {
|
|
1327
|
-
if (Array.isArray(value)) return value[0]
|
|
1328
|
-
return value
|
|
1329
|
-
},
|
|
1330
|
-
|
|
1331
1311
|
isLocalDevelopmentHost(hostname = '') {
|
|
1332
1312
|
if (!hostname || typeof hostname !== 'string') return false
|
|
1333
1313
|
const lower = hostname.toLowerCase()
|
|
@@ -1406,7 +1386,7 @@ export default {
|
|
|
1406
1386
|
if (this.searchingAi) return
|
|
1407
1387
|
if (this.hasRecentManualTabSelection()) return
|
|
1408
1388
|
if (!this.active || this.routeRestoreInProgress) return
|
|
1409
|
-
this.
|
|
1389
|
+
this.restoreSearchState()
|
|
1410
1390
|
},
|
|
1411
1391
|
|
|
1412
1392
|
hasRecentManualTabSelection() {
|
|
@@ -1560,7 +1540,7 @@ export default {
|
|
|
1560
1540
|
},
|
|
1561
1541
|
|
|
1562
1542
|
persistSearchCacheSnapshot(overrides = {}) {
|
|
1563
|
-
const state = this.
|
|
1543
|
+
const state = this.getCurrentSearchState(overrides)
|
|
1564
1544
|
if (!state) return
|
|
1565
1545
|
this.persistSearchState(state, {
|
|
1566
1546
|
cache: this.buildSearchCacheSnapshot(),
|
|
@@ -1673,33 +1653,7 @@ export default {
|
|
|
1673
1653
|
return true
|
|
1674
1654
|
},
|
|
1675
1655
|
|
|
1676
|
-
|
|
1677
|
-
const rawText = this.normalizeRouteQueryValue(
|
|
1678
|
-
routeQuery[SEARCH_ROUTE_QUERY_KEYS.text]
|
|
1679
|
-
)
|
|
1680
|
-
const rawIncludeDistrictResults = this.normalizeRouteQueryValue(
|
|
1681
|
-
routeQuery[SEARCH_ROUTE_QUERY_KEYS.includeDistrictResults]
|
|
1682
|
-
)
|
|
1683
|
-
const rawMode = this.normalizeRouteQueryValue(
|
|
1684
|
-
routeQuery[SEARCH_ROUTE_QUERY_KEYS.mode]
|
|
1685
|
-
)
|
|
1686
|
-
const rawTab = this.normalizeRouteQueryValue(
|
|
1687
|
-
routeQuery[SEARCH_ROUTE_QUERY_KEYS.tab]
|
|
1688
|
-
)
|
|
1689
|
-
const rawUpdatedAt = this.normalizeRouteQueryValue(
|
|
1690
|
-
routeQuery[SEARCH_ROUTE_QUERY_KEYS.updatedAt]
|
|
1691
|
-
)
|
|
1692
|
-
|
|
1693
|
-
return this.normalizeSearchState({
|
|
1694
|
-
text: rawText,
|
|
1695
|
-
mode: rawMode,
|
|
1696
|
-
tab: rawTab,
|
|
1697
|
-
includeDistrictResults: rawIncludeDistrictResults,
|
|
1698
|
-
updatedAt: rawUpdatedAt,
|
|
1699
|
-
})
|
|
1700
|
-
},
|
|
1701
|
-
|
|
1702
|
-
getCurrentSearchStateForRoute(overrides = {}) {
|
|
1656
|
+
getCurrentSearchState(overrides = {}) {
|
|
1703
1657
|
const hasSubmitted =
|
|
1704
1658
|
typeof overrides.hasSubmitted === 'boolean'
|
|
1705
1659
|
? overrides.hasSubmitted
|
|
@@ -1746,35 +1700,17 @@ export default {
|
|
|
1746
1700
|
}
|
|
1747
1701
|
},
|
|
1748
1702
|
|
|
1749
|
-
|
|
1750
|
-
if (!state) return {}
|
|
1751
|
-
const values = {
|
|
1752
|
-
[SEARCH_ROUTE_QUERY_KEYS.text]: state.text,
|
|
1753
|
-
[SEARCH_ROUTE_QUERY_KEYS.mode]: state.mode,
|
|
1754
|
-
[SEARCH_ROUTE_QUERY_KEYS.tab]: state.tab,
|
|
1755
|
-
[SEARCH_ROUTE_QUERY_KEYS.includeDistrictResults]:
|
|
1756
|
-
state.includeDistrictResults ? '1' : '0',
|
|
1757
|
-
}
|
|
1758
|
-
const updatedAt = Number(state.updatedAt)
|
|
1759
|
-
if (Number.isFinite(updatedAt) && updatedAt > 0) {
|
|
1760
|
-
values[SEARCH_ROUTE_QUERY_KEYS.updatedAt] = String(
|
|
1761
|
-
Math.round(updatedAt)
|
|
1762
|
-
)
|
|
1763
|
-
}
|
|
1764
|
-
return values
|
|
1765
|
-
},
|
|
1766
|
-
|
|
1767
|
-
buildQueryWithSearchState(state) {
|
|
1703
|
+
buildQueryWithoutSearchState() {
|
|
1768
1704
|
const nextQuery = { ...((this.$route && this.$route.query) || {}) }
|
|
1769
1705
|
Object.keys(SEARCH_ROUTE_QUERY_KEYS).forEach(key => {
|
|
1770
1706
|
delete nextQuery[SEARCH_ROUTE_QUERY_KEYS[key]]
|
|
1771
1707
|
})
|
|
1772
|
-
return
|
|
1708
|
+
return nextQuery
|
|
1773
1709
|
},
|
|
1774
1710
|
|
|
1775
|
-
async
|
|
1711
|
+
async clearLegacySearchRouteQuery() {
|
|
1776
1712
|
if (!this.$router || !this.$route) return
|
|
1777
|
-
const nextQuery = this.
|
|
1713
|
+
const nextQuery = this.buildQueryWithoutSearchState()
|
|
1778
1714
|
await this.replaceRouteQuery(nextQuery)
|
|
1779
1715
|
},
|
|
1780
1716
|
|
|
@@ -1800,25 +1736,20 @@ export default {
|
|
|
1800
1736
|
async replaceRouteQuery(query) {
|
|
1801
1737
|
if (!this.$router || !this.$route) return
|
|
1802
1738
|
if (this.isSameQuery(this.$route.query, query)) return
|
|
1803
|
-
this.skipNextRouteRestore = true
|
|
1804
1739
|
try {
|
|
1805
1740
|
await this.$router.replace({ path: this.$route.path, query })
|
|
1806
1741
|
} catch (error) {
|
|
1807
|
-
this.skipNextRouteRestore = false
|
|
1808
1742
|
// Ignore duplicate navigation and transient route replacement races.
|
|
1809
1743
|
}
|
|
1810
1744
|
},
|
|
1811
1745
|
|
|
1812
|
-
|
|
1746
|
+
syncSearchState(overrides = {}) {
|
|
1813
1747
|
if (this.routeRestoreInProgress) return
|
|
1814
|
-
|
|
1815
|
-
const state = this.getCurrentSearchStateForRoute(overrides)
|
|
1748
|
+
const state = this.getCurrentSearchState(overrides)
|
|
1816
1749
|
this.lastRestoredSearchKey = state
|
|
1817
|
-
? `
|
|
1750
|
+
? `storage:${JSON.stringify(state)}`
|
|
1818
1751
|
: ''
|
|
1819
1752
|
this.persistSearchState(state, { preserveCache: true })
|
|
1820
|
-
const nextQuery = this.buildQueryWithSearchState(state)
|
|
1821
|
-
await this.replaceRouteQuery(nextQuery)
|
|
1822
1753
|
},
|
|
1823
1754
|
|
|
1824
1755
|
appendSearchContextToUrl(rawUrl) {
|
|
@@ -1826,14 +1757,11 @@ export default {
|
|
|
1826
1757
|
return rawUrl
|
|
1827
1758
|
},
|
|
1828
1759
|
|
|
1829
|
-
async
|
|
1760
|
+
async restoreSearchState() {
|
|
1830
1761
|
if (this.suppressAutoRestore) return
|
|
1831
1762
|
if (this.searchingAi) return
|
|
1832
|
-
if (
|
|
1763
|
+
if (this.routeRestoreInProgress) return
|
|
1833
1764
|
const restoreStartedAt = Date.now()
|
|
1834
|
-
const routeStateCandidate = this.getRouteSearchState(this.$route.query)
|
|
1835
|
-
const routeStateFresh = this.isSearchStateFresh(routeStateCandidate)
|
|
1836
|
-
const routeState = routeStateFresh ? routeStateCandidate : null
|
|
1837
1765
|
const persistedRecordCandidate = this.readPersistedSearchRecord()
|
|
1838
1766
|
const persistedRecordFresh =
|
|
1839
1767
|
persistedRecordCandidate &&
|
|
@@ -1845,24 +1773,16 @@ export default {
|
|
|
1845
1773
|
if (persistedRecordCandidate && !persistedRecordFresh) {
|
|
1846
1774
|
this.persistSearchState(null)
|
|
1847
1775
|
}
|
|
1848
|
-
if (routeStateCandidate && !routeStateFresh) {
|
|
1849
|
-
await this.clearSearchStateFromRouteQuery()
|
|
1850
|
-
}
|
|
1851
1776
|
|
|
1852
|
-
const
|
|
1853
|
-
? null
|
|
1854
|
-
: persistedRecord && persistedRecord.state
|
|
1855
|
-
? persistedRecord.state
|
|
1856
|
-
: null
|
|
1857
|
-
const restoredState = routeState || persistedState
|
|
1777
|
+
const restoredState =
|
|
1778
|
+
persistedRecord && persistedRecord.state ? persistedRecord.state : null
|
|
1858
1779
|
if (!restoredState) return
|
|
1859
1780
|
|
|
1860
|
-
const restoreSource = routeState ? 'route' : 'storage'
|
|
1861
1781
|
const cacheVersion = this.getSearchCacheVersion(
|
|
1862
1782
|
persistedRecord,
|
|
1863
1783
|
restoredState
|
|
1864
1784
|
)
|
|
1865
|
-
const restoreKey =
|
|
1785
|
+
const restoreKey = `storage:${JSON.stringify(
|
|
1866
1786
|
restoredState
|
|
1867
1787
|
)}:${cacheVersion}`
|
|
1868
1788
|
if (restoreKey === this.lastRestoredSearchKey) return
|
|
@@ -1934,9 +1854,14 @@ export default {
|
|
|
1934
1854
|
}
|
|
1935
1855
|
},
|
|
1936
1856
|
|
|
1857
|
+
prepareProgrammaticInput() {
|
|
1858
|
+
this.suppressAutoRestore = true
|
|
1859
|
+
},
|
|
1860
|
+
|
|
1937
1861
|
applyInputText(text, options = {}) {
|
|
1938
1862
|
const submit = !!options.submit
|
|
1939
1863
|
const nextText = typeof text === 'string' ? text : ''
|
|
1864
|
+
this.prepareProgrammaticInput()
|
|
1940
1865
|
this.suppressInputClearReset = true
|
|
1941
1866
|
this.inputText = nextText
|
|
1942
1867
|
|
|
@@ -1946,6 +1871,9 @@ export default {
|
|
|
1946
1871
|
if (submit && nextText.trim()) {
|
|
1947
1872
|
await this.onSubmitInput()
|
|
1948
1873
|
}
|
|
1874
|
+
this.$nextTick(() => {
|
|
1875
|
+
this.suppressAutoRestore = false
|
|
1876
|
+
})
|
|
1949
1877
|
})
|
|
1950
1878
|
},
|
|
1951
1879
|
|
|
@@ -2245,7 +2173,7 @@ export default {
|
|
|
2245
2173
|
|
|
2246
2174
|
dismiss() {
|
|
2247
2175
|
if (!this.active) return
|
|
2248
|
-
this.
|
|
2176
|
+
this.clearLegacySearchRouteQuery()
|
|
2249
2177
|
this.$emit('update:active', false)
|
|
2250
2178
|
},
|
|
2251
2179
|
|
|
@@ -2452,7 +2380,7 @@ export default {
|
|
|
2452
2380
|
await this.clearSearchState()
|
|
2453
2381
|
this.currentTab = 'Answers'
|
|
2454
2382
|
this.persistSearchState(null)
|
|
2455
|
-
|
|
2383
|
+
this.syncSearchState({ hasSubmitted: false, text: '' })
|
|
2456
2384
|
this.lastRestoredSearchKey = ''
|
|
2457
2385
|
|
|
2458
2386
|
this.$nextTick(() => {
|
|
@@ -2594,7 +2522,7 @@ export default {
|
|
|
2594
2522
|
this.searchMode = ''
|
|
2595
2523
|
await this.clearSearchState()
|
|
2596
2524
|
this.persistSearchState(null)
|
|
2597
|
-
|
|
2525
|
+
this.syncSearchState({ hasSubmitted: false, text: '' })
|
|
2598
2526
|
this.lastRestoredSearchKey = ''
|
|
2599
2527
|
this.$nextTick(() => {
|
|
2600
2528
|
this.suppressAutoRestore = false
|
|
@@ -2609,7 +2537,7 @@ export default {
|
|
|
2609
2537
|
this.searchMode = mode
|
|
2610
2538
|
|
|
2611
2539
|
if (mode === 'question') {
|
|
2612
|
-
this.
|
|
2540
|
+
this.syncSearchState({ text, mode, tab: 'Answers' })
|
|
2613
2541
|
this.searchAi(text)
|
|
2614
2542
|
} else {
|
|
2615
2543
|
await this.clearSearchState()
|
|
@@ -2621,7 +2549,7 @@ export default {
|
|
|
2621
2549
|
this.searchFilesWithGroupOwners({ runId })
|
|
2622
2550
|
if (!this.isCurrentSearchRun(runId)) return
|
|
2623
2551
|
this.currentTab = 'Pages'
|
|
2624
|
-
this.
|
|
2552
|
+
this.syncSearchState({ text, mode, tab: 'Pages' })
|
|
2625
2553
|
this.$nextTick(() => this.refreshResultsScrollLayer())
|
|
2626
2554
|
|
|
2627
2555
|
// Log keyword-only search analytics
|
|
@@ -9,8 +9,19 @@
|
|
|
9
9
|
:action-items="actionItems"
|
|
10
10
|
:menu-open="menuOpen"
|
|
11
11
|
:search-open="searchOpen"
|
|
12
|
+
:search-request="homeSearchRequest"
|
|
13
|
+
:pages="searchPages"
|
|
14
|
+
:files="searchFiles"
|
|
15
|
+
:groups="searchGroups"
|
|
16
|
+
:include-district-results="includeDistrictResults"
|
|
17
|
+
:search-language-code="searchLanguageCode"
|
|
18
|
+
:query-pages-handler="queryPagesHandler"
|
|
19
|
+
:query-files-handler="queryFilesHandler"
|
|
20
|
+
:query-groups-handler="queryGroupsHandler"
|
|
21
|
+
:query-ai-site-handler="queryAiSiteHandler"
|
|
12
22
|
:organization="organization"
|
|
13
23
|
:organization-options="organizationOptions"
|
|
24
|
+
:ai-search-feedback-form-url="aiSearchFeedbackFormUrl"
|
|
14
25
|
@update:menuOpen="$emit('update:menuOpen', $event)"
|
|
15
26
|
@update:searchOpen="$emit('update:searchOpen', $event)"
|
|
16
27
|
>
|
|
@@ -63,6 +74,7 @@
|
|
|
63
74
|
:organization="organization"
|
|
64
75
|
:organization-options="organizationOptions"
|
|
65
76
|
:ai-search-feedback-form-url="aiSearchFeedbackFormUrl"
|
|
77
|
+
@submit-search="onHomeSearchSubmit"
|
|
66
78
|
/>
|
|
67
79
|
</client-only>
|
|
68
80
|
|
|
@@ -218,6 +230,7 @@ export default {
|
|
|
218
230
|
aiSearchFeedbackFormUrl: { type: String, default: '' },
|
|
219
231
|
},
|
|
220
232
|
data: () => ({
|
|
233
|
+
homeSearchRequest: null,
|
|
221
234
|
factoids: [
|
|
222
235
|
{
|
|
223
236
|
start: 0,
|
|
@@ -249,6 +262,14 @@ export default {
|
|
|
249
262
|
},
|
|
250
263
|
],
|
|
251
264
|
}),
|
|
265
|
+
methods: {
|
|
266
|
+
onHomeSearchSubmit(request) {
|
|
267
|
+
this.homeSearchRequest = {
|
|
268
|
+
...request,
|
|
269
|
+
requestedAt: Date.now(),
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
},
|
|
252
273
|
}
|
|
253
274
|
</script>
|
|
254
275
|
|
|
@@ -9,8 +9,19 @@
|
|
|
9
9
|
:action-items="actionItems"
|
|
10
10
|
:menu-open="menuOpen"
|
|
11
11
|
:search-open="searchOpen"
|
|
12
|
+
:search-request="homeSearchRequest"
|
|
13
|
+
:pages="searchPages"
|
|
14
|
+
:files="searchFiles"
|
|
15
|
+
:groups="searchGroups"
|
|
16
|
+
:include-district-results="includeDistrictResults"
|
|
17
|
+
:search-language-code="searchLanguageCode"
|
|
18
|
+
:query-pages-handler="queryPagesHandler"
|
|
19
|
+
:query-files-handler="queryFilesHandler"
|
|
20
|
+
:query-groups-handler="queryGroupsHandler"
|
|
21
|
+
:query-ai-site-handler="queryAiSiteHandler"
|
|
12
22
|
:organization-options="organizationOptions"
|
|
13
23
|
:organization="organization"
|
|
24
|
+
:ai-search-feedback-form-url="aiSearchFeedbackFormUrl"
|
|
14
25
|
@update:menuOpen="$emit('update:menuOpen', $event)"
|
|
15
26
|
@update:searchOpen="$emit('update:searchOpen', $event)"
|
|
16
27
|
/>
|
|
@@ -107,6 +118,7 @@
|
|
|
107
118
|
:organization="organization"
|
|
108
119
|
:organization-options="organizationOptions"
|
|
109
120
|
:ai-search-feedback-form-url="aiSearchFeedbackFormUrl"
|
|
121
|
+
@submit-search="onHomeSearchSubmit"
|
|
110
122
|
/>
|
|
111
123
|
</client-only>
|
|
112
124
|
<Asd20BlockSchedule
|
|
@@ -233,6 +245,7 @@ export default {
|
|
|
233
245
|
|
|
234
246
|
data: () => ({
|
|
235
247
|
showLogo: true,
|
|
248
|
+
homeSearchRequest: null,
|
|
236
249
|
}),
|
|
237
250
|
|
|
238
251
|
computed: {
|
|
@@ -316,6 +329,12 @@ export default {
|
|
|
316
329
|
download: event.currentTarget?.hasAttribute?.('download'),
|
|
317
330
|
})
|
|
318
331
|
},
|
|
332
|
+
onHomeSearchSubmit(request) {
|
|
333
|
+
this.homeSearchRequest = {
|
|
334
|
+
...request,
|
|
335
|
+
requestedAt: Date.now(),
|
|
336
|
+
}
|
|
337
|
+
},
|
|
319
338
|
},
|
|
320
339
|
}
|
|
321
340
|
</script>
|
|
@@ -9,8 +9,19 @@
|
|
|
9
9
|
:action-items="actionItems"
|
|
10
10
|
:menu-open="menuOpen"
|
|
11
11
|
:search-open="searchOpen"
|
|
12
|
+
:search-request="homeSearchRequest"
|
|
13
|
+
:pages="searchPages"
|
|
14
|
+
:files="searchFiles"
|
|
15
|
+
:groups="searchGroups"
|
|
16
|
+
:include-district-results="includeDistrictResults"
|
|
17
|
+
:search-language-code="searchLanguageCode"
|
|
18
|
+
:query-pages-handler="queryPagesHandler"
|
|
19
|
+
:query-files-handler="queryFilesHandler"
|
|
20
|
+
:query-groups-handler="queryGroupsHandler"
|
|
21
|
+
:query-ai-site-handler="queryAiSiteHandler"
|
|
12
22
|
:organization="organization"
|
|
13
23
|
:organization-options="organizationOptions"
|
|
24
|
+
:ai-search-feedback-form-url="aiSearchFeedbackFormUrl"
|
|
14
25
|
@update:menuOpen="$emit('update:menuOpen', $event)"
|
|
15
26
|
@update:searchOpen="$emit('update:searchOpen', $event)"
|
|
16
27
|
/>
|
|
@@ -108,6 +119,7 @@
|
|
|
108
119
|
:organization="organization"
|
|
109
120
|
:organization-options="organizationOptions"
|
|
110
121
|
:ai-search-feedback-form-url="aiSearchFeedbackFormUrl"
|
|
122
|
+
@submit-search="onHomeSearchSubmit"
|
|
111
123
|
/>
|
|
112
124
|
</client-only>
|
|
113
125
|
|
|
@@ -235,6 +247,9 @@ export default {
|
|
|
235
247
|
queryAiSiteHandler: { type: Function, default: null },
|
|
236
248
|
aiSearchFeedbackFormUrl: { type: String, default: '' },
|
|
237
249
|
},
|
|
250
|
+
data: () => ({
|
|
251
|
+
homeSearchRequest: null,
|
|
252
|
+
}),
|
|
238
253
|
computed: {
|
|
239
254
|
blockEvent() {
|
|
240
255
|
if (!this.events || this.events.length === 0) return null
|
|
@@ -269,6 +284,12 @@ export default {
|
|
|
269
284
|
}
|
|
270
285
|
},
|
|
271
286
|
methods: {
|
|
287
|
+
onHomeSearchSubmit(request) {
|
|
288
|
+
this.homeSearchRequest = {
|
|
289
|
+
...request,
|
|
290
|
+
requestedAt: Date.now(),
|
|
291
|
+
}
|
|
292
|
+
},
|
|
272
293
|
onLogoClick(event, link) {
|
|
273
294
|
navigateInternalHref(this, event, link, {
|
|
274
295
|
target: event.currentTarget?.getAttribute?.('target'),
|