fix: search store now parses API envelope response correctly
The search API returns { success, data: [...] } but the store was
looking for data.apps and data.boards (which don't exist). Fixed to
read from data.data[] and also added url/icon fields to search API
response so app results are clickable and show icons.
This commit is contained in:
@@ -100,31 +100,28 @@ class SearchStore {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await res.json();
|
const json = await res.json();
|
||||||
|
const results = json.data ?? [];
|
||||||
const items: SearchResultItem[] = [];
|
const items: SearchResultItem[] = [];
|
||||||
|
|
||||||
if (data.apps) {
|
for (const item of results) {
|
||||||
for (const app of data.apps) {
|
if (item.type === 'app') {
|
||||||
items.push({
|
items.push({
|
||||||
type: 'app',
|
type: 'app',
|
||||||
id: app.id,
|
id: item.id,
|
||||||
name: app.name,
|
name: item.name,
|
||||||
description: app.description ?? null,
|
description: item.description ?? null,
|
||||||
url: app.url,
|
url: item.url ?? `/apps/${item.id}`,
|
||||||
icon: app.icon ?? null
|
icon: item.icon ?? null
|
||||||
});
|
});
|
||||||
}
|
} else if (item.type === 'board') {
|
||||||
}
|
|
||||||
|
|
||||||
if (data.boards) {
|
|
||||||
for (const board of data.boards) {
|
|
||||||
items.push({
|
items.push({
|
||||||
type: 'board',
|
type: 'board',
|
||||||
id: board.id,
|
id: item.id,
|
||||||
name: board.name,
|
name: item.name,
|
||||||
description: board.description ?? null,
|
description: item.description ?? null,
|
||||||
url: `/boards/${board.id}`,
|
url: `/boards/${item.id}`,
|
||||||
icon: board.icon ?? null
|
icon: item.icon ?? null
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ interface SearchResult {
|
|||||||
readonly id: string;
|
readonly id: string;
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
readonly description: string | null;
|
readonly description: string | null;
|
||||||
|
readonly url?: string;
|
||||||
|
readonly icon?: string | null;
|
||||||
readonly category?: string | null;
|
readonly category?: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,6 +41,9 @@ export const GET: RequestHandler = async (event) => {
|
|||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
name: true,
|
name: true,
|
||||||
|
url: true,
|
||||||
|
icon: true,
|
||||||
|
iconType: true,
|
||||||
description: true,
|
description: true,
|
||||||
category: true
|
category: true
|
||||||
},
|
},
|
||||||
@@ -66,14 +71,18 @@ export const GET: RequestHandler = async (event) => {
|
|||||||
// Filter apps by permission
|
// Filter apps by permission
|
||||||
const filteredApps: SearchResult[] = [];
|
const filteredApps: SearchResult[] = [];
|
||||||
for (const app of apps) {
|
for (const app of apps) {
|
||||||
if (isAdmin) {
|
const appResult: SearchResult = {
|
||||||
filteredApps.push({
|
|
||||||
type: 'app',
|
type: 'app',
|
||||||
id: app.id,
|
id: app.id,
|
||||||
name: app.name,
|
name: app.name,
|
||||||
description: app.description,
|
description: app.description,
|
||||||
|
url: app.url,
|
||||||
|
icon: app.icon,
|
||||||
category: app.category
|
category: app.category
|
||||||
});
|
};
|
||||||
|
|
||||||
|
if (isAdmin) {
|
||||||
|
filteredApps.push(appResult);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,13 +93,7 @@ export const GET: RequestHandler = async (event) => {
|
|||||||
PermissionLevel.VIEW
|
PermissionLevel.VIEW
|
||||||
);
|
);
|
||||||
if (check.hasPermission) {
|
if (check.hasPermission) {
|
||||||
filteredApps.push({
|
filteredApps.push(appResult);
|
||||||
type: 'app',
|
|
||||||
id: app.id,
|
|
||||||
name: app.name,
|
|
||||||
description: app.description,
|
|
||||||
category: app.category
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user