- {hits.map((item) => (
-
-
-
-
- {item.title}
-
-
-
-
-
- {t("viewFeature")}
-
+ {hits.map((item) => {
+ const href = item.url ?? ""
+ const isExternal = /^https?:\/\//.test(href)
+ const iconComponent = item.icon
+ ? ({
+ media: item.icon,
+ alt: item.icon.alternativeText ?? item.title,
+ } as unknown as Data.Component<"utilities.basic-image">)
+ : null
+
+ return (
+
+ {item.feature_tag && (
+
+ {item.feature_tag}
-
-
-
- ))}
+ )}
+
+
+
+ {iconComponent && (
+
+ )}
+
+
+ {item.title}
+
+
+ {item.description && (
+
+ {item.description}
+
+ )}
+
+
+
+ )
+ })}
{hasMore && (
diff --git a/apps/ui/src/components/feature-page/feature-pages-search-types.ts b/apps/ui/src/components/feature-page/feature-pages-search-types.ts
index d0c80c3..2643bc9 100644
--- a/apps/ui/src/components/feature-page/feature-pages-search-types.ts
+++ b/apps/ui/src/components/feature-page/feature-pages-search-types.ts
@@ -1,11 +1,19 @@
+export interface FeatureIconMedia {
+ readonly url?: string
+ readonly alternativeText?: string | null
+ readonly width?: number
+ readonly height?: number
+}
+
export interface FeaturePageHit {
readonly id?: number
readonly documentId?: string
- readonly slug: string
readonly title: string
- readonly fullPath: string
+ readonly description?: string | null
+ readonly url?: string | null
+ readonly feature_tag?: string | null
+ readonly icon?: FeatureIconMedia | null
readonly locale?: string
- readonly pageType?: string
readonly [key: string]: unknown
}
@@ -17,6 +25,7 @@ export interface FeaturePagesSearchResult {
export interface SearchFeaturePagesArgs {
readonly locale: string
readonly query: string
+ readonly featureTagTitles: readonly string[]
readonly offset: number
readonly limit: number
}
diff --git a/apps/ui/src/components/feature-page/feature-pages-search.ts b/apps/ui/src/components/feature-page/feature-pages-search.ts
index 7a30ec3..27267f3 100644
--- a/apps/ui/src/components/feature-page/feature-pages-search.ts
+++ b/apps/ui/src/components/feature-page/feature-pages-search.ts
@@ -1,6 +1,6 @@
"use server"
-import { getMeilisearchClient, getPagesIndexName } from "@/lib/meilisearch"
+import { getFeaturesIndexName, getMeilisearchClient } from "@/lib/meilisearch"
import type {
FeaturePageHit,
@@ -14,18 +14,21 @@ function escape(value: string): string {
}
export async function searchFeaturePages({
- locale,
query,
+ featureTagTitles,
offset,
limit,
}: SearchFeaturePagesArgs): Promise
{
- const index =
- getMeilisearchClient().index(getPagesIndexName())
+ const index = getMeilisearchClient().index(
+ getFeaturesIndexName()
+ )
- const filter: string[] = [
- `pageType = "feature"`,
- `locale = "${escape(locale)}"`,
- ]
+ const filter: string[] = []
+
+ if (featureTagTitles.length > 0) {
+ const list = featureTagTitles.map((t) => `"${escape(t)}"`).join(", ")
+ filter.push(`feature_tag IN [${list}]`)
+ }
const res = await index.search(query.trim(), {
offset,
diff --git a/apps/ui/src/components/page-builder/components/sections/strapi-dynamic-grid/StrapiDynamicFeaturesGrid.tsx b/apps/ui/src/components/page-builder/components/sections/strapi-dynamic-grid/StrapiDynamicFeaturesGrid.tsx
index 5aae414..ef12b65 100644
--- a/apps/ui/src/components/page-builder/components/sections/strapi-dynamic-grid/StrapiDynamicFeaturesGrid.tsx
+++ b/apps/ui/src/components/page-builder/components/sections/strapi-dynamic-grid/StrapiDynamicFeaturesGrid.tsx
@@ -22,6 +22,7 @@ export function StrapiDynamicFeaturesGrid({
searchFeaturePages({
locale,
query: "",
+ featureTagTitles: [],
offset: 0,
limit: INITIAL_PAGE_SIZE,
})
diff --git a/apps/ui/src/lib/meilisearch.ts b/apps/ui/src/lib/meilisearch.ts
index 991e4bb..e726691 100644
--- a/apps/ui/src/lib/meilisearch.ts
+++ b/apps/ui/src/lib/meilisearch.ts
@@ -53,3 +53,9 @@ export function getBlogPostsIndexName(): string {
? "blog-posts-production"
: "blog-posts-testing"
}
+
+export function getFeaturesIndexName(): string {
+ return process.env.MEILISEARCH_PRODUCTION === "true"
+ ? "features-production"
+ : "features-testing"
+}