@asd20/ui-next 2.29.0 → 2.29.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.29.1](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.29.0...ui-next-v2.29.1) (2026-10-05)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* carry ai search verified supporting pages into related pages and pages tab ([46253e0](https://github.com/academydistrict20/asd20-ui-next/commit/46253e05ef064c99dbe3151cd093f6c938e2e9f6))
|
|
9
|
+
|
|
3
10
|
# [2.29.0](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.28.1...ui-next-v2.29.0) (2026-10-02)
|
|
4
11
|
|
|
5
12
|
|
package/package.json
CHANGED
|
@@ -2701,6 +2701,12 @@ export default {
|
|
|
2701
2701
|
question: this.searchQuestion || this.inputText,
|
|
2702
2702
|
}
|
|
2703
2703
|
if (options.purpose) searchInput.purpose = options.purpose
|
|
2704
|
+
if (
|
|
2705
|
+
options.purpose === 'ai-related-pages' &&
|
|
2706
|
+
options.sourcePages?.length
|
|
2707
|
+
) {
|
|
2708
|
+
searchInput.sourcePages = options.sourcePages
|
|
2709
|
+
}
|
|
2704
2710
|
|
|
2705
2711
|
this.searchingPages = true
|
|
2706
2712
|
try {
|
|
@@ -3105,6 +3111,16 @@ export default {
|
|
|
3105
3111
|
? `[Keywords: ${keywordsToUse.replace(/<[^>]*>/g, '')}]`
|
|
3106
3112
|
: ''
|
|
3107
3113
|
|
|
3114
|
+
const sourcePages = Array.isArray(sources)
|
|
3115
|
+
? sources
|
|
3116
|
+
.filter(
|
|
3117
|
+
source =>
|
|
3118
|
+
typeof source?.url === 'string' &&
|
|
3119
|
+
typeof source?.chunkId === 'string'
|
|
3120
|
+
)
|
|
3121
|
+
.slice(0, 8)
|
|
3122
|
+
.map(({ url, chunkId }) => ({ url, chunkId }))
|
|
3123
|
+
: []
|
|
3108
3124
|
const assistantTurnKeywords = safeKeywords || keywordsToUse || ''
|
|
3109
3125
|
const assistantTurn = {
|
|
3110
3126
|
id: `a-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
@@ -3115,7 +3131,8 @@ export default {
|
|
|
3115
3131
|
feedbackValue: null,
|
|
3116
3132
|
feedbackSubmitting: false,
|
|
3117
3133
|
relatedPages: [],
|
|
3118
|
-
relatedPagesStatus:
|
|
3134
|
+
relatedPagesStatus:
|
|
3135
|
+
keywordsToUse || sourcePages.length ? 'pending' : 'complete',
|
|
3119
3136
|
}
|
|
3120
3137
|
assistantTurnId = assistantTurn.id
|
|
3121
3138
|
this.aiTranscript = [...this.aiTranscript, assistantTurn]
|
|
@@ -3124,13 +3141,14 @@ export default {
|
|
|
3124
3141
|
this.scrollTurnToTop(this.anchoredUserTurnId, { defer: true })
|
|
3125
3142
|
}
|
|
3126
3143
|
|
|
3127
|
-
if (keywordsToUse) {
|
|
3144
|
+
if (keywordsToUse || sourcePages.length) {
|
|
3128
3145
|
this.keywordsFromAi = true
|
|
3129
3146
|
this.skipKeywordWatcher = true
|
|
3130
3147
|
this.keywords = keywordsToUse
|
|
3131
3148
|
await this.searchPages({
|
|
3132
3149
|
keepAnswersTab: true,
|
|
3133
3150
|
purpose: 'ai-related-pages',
|
|
3151
|
+
sourcePages,
|
|
3134
3152
|
runId,
|
|
3135
3153
|
})
|
|
3136
3154
|
if (!this.isCurrentSearchRun(runId)) return
|
|
@@ -3,6 +3,7 @@ import axios from 'axios'
|
|
|
3
3
|
import { hasSearchProxyRuntime, resolveSearchProxyUrl } from './searchProxyUrl'
|
|
4
4
|
import { resolveRuntimeConfigValue } from './runtimeConfig'
|
|
5
5
|
import { buildTypoTolerantSearchQuery } from './searchQuery'
|
|
6
|
+
import { mergeSupportingPages } from './supportingPages'
|
|
6
7
|
|
|
7
8
|
export const NO_PAGE_RESULTS_FALLBACKS = [
|
|
8
9
|
{
|
|
@@ -100,6 +101,8 @@ function searchPayload(state) {
|
|
|
100
101
|
*/
|
|
101
102
|
export default async function queryPages({
|
|
102
103
|
keywords = '',
|
|
104
|
+
purpose = '',
|
|
105
|
+
sourcePages = [],
|
|
103
106
|
top = 25,
|
|
104
107
|
requireKeywords = false,
|
|
105
108
|
organizations = [],
|
|
@@ -111,7 +114,11 @@ export default async function queryPages({
|
|
|
111
114
|
apiVersion = '',
|
|
112
115
|
searchVersion = '',
|
|
113
116
|
}) {
|
|
114
|
-
|
|
117
|
+
const supportingSources =
|
|
118
|
+
purpose === 'ai-related-pages' && Array.isArray(sourcePages)
|
|
119
|
+
? sourcePages.slice(0, 8)
|
|
120
|
+
: []
|
|
121
|
+
if (!keywords && requireKeywords && !supportingSources.length)
|
|
115
122
|
return {
|
|
116
123
|
pages: [],
|
|
117
124
|
facets: [],
|
|
@@ -150,16 +157,17 @@ export default async function queryPages({
|
|
|
150
157
|
const resolvedRequestUrl =
|
|
151
158
|
typeof requestUrl === 'string' && requestUrl.trim()
|
|
152
159
|
? requestUrl.trim()
|
|
153
|
-
: !resolvedSearchEndpoint &&
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
: ''
|
|
160
|
+
: !resolvedSearchEndpoint && hasSearchProxyRuntime(runtimeConfig)
|
|
161
|
+
? resolveSearchProxyUrl('pages', runtimeConfig)
|
|
162
|
+
: ''
|
|
157
163
|
|
|
158
164
|
if (
|
|
159
165
|
!resolvedRequestUrl &&
|
|
160
166
|
(!resolvedSearchEndpoint || !resolvedSearchKey || !resolvedApiVersion)
|
|
161
167
|
) {
|
|
162
|
-
throw new Error(
|
|
168
|
+
throw new Error(
|
|
169
|
+
'Azure Search or proxy configuration is required for queryPages.'
|
|
170
|
+
)
|
|
163
171
|
}
|
|
164
172
|
|
|
165
173
|
const { data } = resolvedRequestUrl
|
|
@@ -170,6 +178,9 @@ export default async function queryPages({
|
|
|
170
178
|
keywords,
|
|
171
179
|
organizations,
|
|
172
180
|
top,
|
|
181
|
+
...(supportingSources.length
|
|
182
|
+
? { sourcePages: supportingSources }
|
|
183
|
+
: {}),
|
|
173
184
|
},
|
|
174
185
|
})
|
|
175
186
|
: await axios({
|
|
@@ -194,10 +205,15 @@ export default async function queryPages({
|
|
|
194
205
|
),
|
|
195
206
|
})
|
|
196
207
|
|
|
197
|
-
const pages =
|
|
208
|
+
const pages = mergeSupportingPages(
|
|
209
|
+
Array.isArray(data.value) ? data.value : [],
|
|
210
|
+
Array.isArray(data.supportingPages) ? data.supportingPages : [],
|
|
211
|
+
supportingSources,
|
|
212
|
+
organizations
|
|
213
|
+
)
|
|
198
214
|
const resolvedPages = pages.length
|
|
199
215
|
? pages
|
|
200
|
-
: NO_PAGE_RESULTS_FALLBACKS.map(
|
|
216
|
+
: NO_PAGE_RESULTS_FALLBACKS.map(page => ({
|
|
201
217
|
...page,
|
|
202
218
|
categories: Array.isArray(page.categories) ? [...page.categories] : [],
|
|
203
219
|
}))
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export function normalizeSupportingPageUrl(value) {
|
|
2
|
+
if (typeof value !== 'string' || value.length > 2048) return ''
|
|
3
|
+
try {
|
|
4
|
+
const url = new URL(value.trim())
|
|
5
|
+
if (
|
|
6
|
+
!['http:', 'https:'].includes(url.protocol) ||
|
|
7
|
+
url.username ||
|
|
8
|
+
url.password
|
|
9
|
+
)
|
|
10
|
+
return ''
|
|
11
|
+
url.hash = ''
|
|
12
|
+
url.pathname = url.pathname.replace(/\/+$/, '') || '/'
|
|
13
|
+
return url.toString().replace(/\/$/, '')
|
|
14
|
+
} catch (_error) {
|
|
15
|
+
return ''
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function mergeSupportingPages(
|
|
20
|
+
pages = [],
|
|
21
|
+
supportingPages = [],
|
|
22
|
+
sourcePages = [],
|
|
23
|
+
organizations = []
|
|
24
|
+
) {
|
|
25
|
+
const sourceUrls = sourcePages
|
|
26
|
+
.map(source => normalizeSupportingPageUrl(source?.url))
|
|
27
|
+
.filter(Boolean)
|
|
28
|
+
const supported = supportingPages
|
|
29
|
+
.filter(
|
|
30
|
+
page =>
|
|
31
|
+
page.type === 'page' &&
|
|
32
|
+
sourceUrls.includes(normalizeSupportingPageUrl(page.url)) &&
|
|
33
|
+
(!organizations.length ||
|
|
34
|
+
organizations.includes(page.ownerOrganizationId))
|
|
35
|
+
)
|
|
36
|
+
.sort(
|
|
37
|
+
(a, b) =>
|
|
38
|
+
sourceUrls.indexOf(normalizeSupportingPageUrl(a.url)) -
|
|
39
|
+
sourceUrls.indexOf(normalizeSupportingPageUrl(b.url))
|
|
40
|
+
)
|
|
41
|
+
if (!supported.length) return pages
|
|
42
|
+
const seen = new Set()
|
|
43
|
+
return [
|
|
44
|
+
...supported.map(page => ({ ...page, isAnswerSupportingPage: true })),
|
|
45
|
+
...pages,
|
|
46
|
+
].filter(page => {
|
|
47
|
+
const key = normalizeSupportingPageUrl(page.url) || page.id
|
|
48
|
+
if (!key) return true
|
|
49
|
+
if (seen.has(key)) return false
|
|
50
|
+
seen.add(key)
|
|
51
|
+
return true
|
|
52
|
+
})
|
|
53
|
+
}
|