@grove-dev/astro 0.2.13 → 0.2.14
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/README.md +26 -18
- package/dist/lib/repo.d.ts +2 -1
- package/dist/lib/repo.d.ts.map +1 -1
- package/dist/lib/repo.js +2 -1
- package/dist/lib/repo.js.map +1 -1
- package/dist/lib/search.d.ts +13 -16
- package/dist/lib/search.d.ts.map +1 -1
- package/dist/lib/search.js +6 -9
- package/dist/lib/search.js.map +1 -1
- package/package.json +3 -3
- package/src/components/RecordSection.astro +2 -1
- package/src/components/RefinePanel.astro +3 -3
- package/src/lib/repo.ts +2 -1
- package/src/lib/search.ts +26 -31
- package/src/styles.css +3 -1
- package/templates/default/package.json +3 -3
- package/templates/default/public/llms-full.txt +1 -1
- package/templates/default/public/sitemap.xml +10 -10
- package/templates/default/src/data/records.ts +8 -4
- package/templates/default/src/pages/[slug]/{[itemSlug].astro → [recordSlug].astro} +3 -3
- package/templates/default/src/pages/[slug]/index.astro +16 -15
- package/templates/default/src/pages/apps/[recordSlug].astro +33 -0
- package/templates/default/src/pages/apps/[itemSlug].astro +0 -301
- package/templates/default/src/pages/apps/index.astro +0 -146
- /package/src/components/{AppsIndexRow.astro → IndexRow.astro} +0 -0
- /package/src/components/{AppsPagination.astro → Pagination.astro} +0 -0
package/README.md
CHANGED
|
@@ -12,33 +12,40 @@ pnpm add @grove-dev/astro
|
|
|
12
12
|
|
|
13
13
|
```txt
|
|
14
14
|
src/
|
|
15
|
-
├── components/ # ItemCard, CategoryGrid,
|
|
16
|
-
│ #
|
|
17
|
-
│ #
|
|
18
|
-
│ #
|
|
15
|
+
├── components/ # ItemCard, CategoryGrid, ScoreBars, IndexRow,
|
|
16
|
+
│ # Pagination, RecordSection, RefinePanel, Hero,
|
|
17
|
+
│ # Icon, SmartLensTabs, ExploreByCategory,
|
|
18
|
+
│ # ExploreByStack, WhyThisExists, CurationGrid,
|
|
19
|
+
│ # ContributorsGrid, StackGrid, MinimalAbout,
|
|
20
|
+
│ # OriginalCollection, DecisionRow, FilterGroupMenu,
|
|
21
|
+
│ # FilterOptions
|
|
19
22
|
├── layouts/ # BaseLayout
|
|
20
23
|
├── styles.css # design tokens + utility classes
|
|
21
|
-
└── index.ts # re-exports @grove-dev/ui
|
|
24
|
+
└── index.ts # re-exports @grove-dev/core + @grove-dev/ui
|
|
22
25
|
|
|
23
26
|
templates/
|
|
24
27
|
└── default/ # full Astro starter: pages/, layouts/, public/, data/,
|
|
25
|
-
# .github/, astro.config.mjs
|
|
28
|
+
# .github/, astro.config.mjs
|
|
26
29
|
```
|
|
27
30
|
|
|
28
31
|
The package publishes `dist/`, `src/`, and `templates/`. The `templates/` directory is **not** imported by consumers; it is copied by `@grove-dev/cli` at scaffold time.
|
|
29
32
|
|
|
33
|
+
> **Component naming:** `ItemCard` is the V1 published API name (kept for stability — it appears in user docs and downstream sites). The internal `IndexRow` / `Pagination` / `RecordSection` aliases are V1 canonical names; the old `AppsIndexRow` / `AppsPagination` / `ItemSection` V0 names have been removed.
|
|
34
|
+
|
|
30
35
|
## Usage in a space
|
|
31
36
|
|
|
32
37
|
```astro
|
|
33
38
|
---
|
|
34
|
-
import
|
|
39
|
+
import ItemCard from "@grove-dev/astro/components/ItemCard.astro";
|
|
40
|
+
import IndexRow from "@grove-dev/astro/components/IndexRow.astro";
|
|
41
|
+
import { ScoreBars, filterRecords, sortDisplay } from "@grove-dev/astro";
|
|
35
42
|
import "@grove-dev/astro/styles.css";
|
|
36
43
|
import BaseLayout from "@grove-dev/astro/layouts/BaseLayout.astro";
|
|
37
|
-
import
|
|
44
|
+
import records from "../data/generated/records.json";
|
|
38
45
|
---
|
|
39
46
|
<BaseLayout title="My Grove space">
|
|
40
|
-
<
|
|
41
|
-
{
|
|
47
|
+
<RefinePanel initial={filters} facets={facets} />
|
|
48
|
+
{records.map((r) => <ItemCard record={r} href={`/projects/${r.slug}`} />)}
|
|
42
49
|
</BaseLayout>
|
|
43
50
|
```
|
|
44
51
|
|
|
@@ -48,16 +55,17 @@ Components are imported by path, not through the barrel — that lets `astro che
|
|
|
48
55
|
|
|
49
56
|
`templates/default/` is a complete Astro starter. It contains:
|
|
50
57
|
|
|
51
|
-
- `src/pages/` — index,
|
|
52
|
-
- `src/components/` —
|
|
53
|
-
- `src/data
|
|
58
|
+
- `src/pages/` — index, contributors, about, submit, 404, sitemap.xml, plus blueprint-aware dynamic routes at `[slug]/index.astro` (list) and `[slug]/[recordSlug].astro` (detail), plus `apps/[recordSlug].astro` (V0→V1 301 redirect)
|
|
59
|
+
- `src/components/` — site-specific page sections (none by default; the V1 surface is in `packages/astro/src/components/`)
|
|
60
|
+
- `src/data/records.ts` — typed loader for `data/generated/records.full.json` (V0 `src/data/config.ts` is replaced)
|
|
54
61
|
- `src/lib/` — site-specific helpers (no business logic)
|
|
55
|
-
- `
|
|
56
|
-
- `
|
|
57
|
-
- `
|
|
58
|
-
-
|
|
62
|
+
- `scripts/` — `build-llms.mjs` (regenerates `llms-full.txt` only, preserves committed `llms.txt`), `fetch-icons.mjs`, `migrate-legacy-to-schema-v1.mjs`
|
|
63
|
+
- `public/` — icons, OG image, robots, `llms.txt`, `llms-full.txt`
|
|
64
|
+
- `data/` — empty tree for the gardener to populate; `data/records/<slug>.yml` is the V1 layout (V0 was `data/apps/*.yml`)
|
|
65
|
+
- `astro.config.mjs` (no `tailwind.config.mjs` by default; plain CSS + design tokens)
|
|
66
|
+
- `.github/` — issue templates + 11 GitHub Actions workflows (validate, build, deploy, sync, cleanup, …)
|
|
59
67
|
|
|
60
|
-
Business logic (filtering, sorting, scoring, faceting) is **imported from `@grove-dev/ui`**, never re-implemented in the template.
|
|
68
|
+
Business logic (filtering, sorting, scoring, faceting) is **imported from `@grove-dev/ui`**, never re-implemented in the template. The V0 commands (`grove build-data`, `grove build-llms-full`, `grove analyze`, `grove enrich`) have been replaced with V1 names (`grove generate`, `grove llms`, `grove sync github`).
|
|
61
69
|
|
|
62
70
|
## Layering
|
|
63
71
|
|
package/dist/lib/repo.d.ts
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* Returns nulls if the URL doesn't match github.com/{owner}/{repo}.
|
|
4
4
|
*
|
|
5
5
|
* Used in:
|
|
6
|
-
* - ItemCard avatar fallback (owner avatar via GitHub avatars
|
|
6
|
+
* - ItemCard avatar fallback (owner avatar via GitHub avatars
|
|
7
|
+
* API; component name retained for V1 published API stability)
|
|
7
8
|
* - App detail page (showing owner + repo name in breadcrumb / header)
|
|
8
9
|
* - Anywhere we need to display "@owner / repo" or link to the owner
|
|
9
10
|
*/
|
package/dist/lib/repo.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../src/lib/repo.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../src/lib/repo.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG;IAC3D,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB,CAUA;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,GAAE,MAAW,GAAG,MAAM,GAAG,IAAI,CAGxF"}
|
package/dist/lib/repo.js
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* Returns nulls if the URL doesn't match github.com/{owner}/{repo}.
|
|
4
4
|
*
|
|
5
5
|
* Used in:
|
|
6
|
-
* - ItemCard avatar fallback (owner avatar via GitHub avatars
|
|
6
|
+
* - ItemCard avatar fallback (owner avatar via GitHub avatars
|
|
7
|
+
* API; component name retained for V1 published API stability)
|
|
7
8
|
* - App detail page (showing owner + repo name in breadcrumb / header)
|
|
8
9
|
* - Anywhere we need to display "@owner / repo" or link to the owner
|
|
9
10
|
*/
|
package/dist/lib/repo.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repo.js","sourceRoot":"","sources":["../../src/lib/repo.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"repo.js","sourceRoot":"","sources":["../../src/lib/repo.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,UAAU,0BAA0B,CAAC,OAAe;IAIxD,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QACjD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACrC,CAAC;IACD,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;IAC3D,IAAI,CAAC,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC3C,OAAO;QACL,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;QACX,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;KACjC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAoB,EAAE,OAAe,EAAE;IACvE,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,OAAO,yCAAyC,KAAK,UAAU,IAAI,EAAE,CAAC;AACxE,CAAC"}
|
package/dist/lib/search.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { IndexRecord } from "@grove-dev/core";
|
|
|
5
5
|
* Multi-value fields use repeated keys in the URL: `?stack=Flutter&stack=React+Native`.
|
|
6
6
|
* Empty / undefined fields mean "no filter on this dimension".
|
|
7
7
|
*/
|
|
8
|
-
export type
|
|
8
|
+
export type IndexFilters = {
|
|
9
9
|
q?: string;
|
|
10
10
|
stacks?: string[];
|
|
11
11
|
platforms?: string[];
|
|
@@ -16,7 +16,7 @@ export type ItemsFilters = {
|
|
|
16
16
|
/** A curated lens (e.g. "good-to-learn", "production-like"). Single value. */
|
|
17
17
|
lens?: string;
|
|
18
18
|
/** Sort order. Single value, defaults to "recently-updated". */
|
|
19
|
-
sort?:
|
|
19
|
+
sort?: IndexSort;
|
|
20
20
|
/** 1-based page number. */
|
|
21
21
|
page?: number;
|
|
22
22
|
};
|
|
@@ -37,31 +37,31 @@ export declare const SORT_OPTIONS: readonly [{
|
|
|
37
37
|
readonly value: "alphabetical";
|
|
38
38
|
readonly label: "Alphabetical";
|
|
39
39
|
}];
|
|
40
|
-
export type
|
|
40
|
+
export type IndexSort = (typeof SORT_OPTIONS)[number]["value"];
|
|
41
41
|
/**
|
|
42
42
|
* Read filters from a URLSearchParams (or anything URLSearchParams-shaped,
|
|
43
43
|
* e.g. the result of `new URL(req.url).searchParams`).
|
|
44
44
|
*/
|
|
45
|
-
export declare function filtersFromSearchParams(sp: URLSearchParams):
|
|
45
|
+
export declare function filtersFromSearchParams(sp: URLSearchParams): IndexFilters;
|
|
46
46
|
/**
|
|
47
47
|
* Serialize a filters object back to URLSearchParams.
|
|
48
48
|
* Undefined / empty values are dropped. Defaults (sort, page 1, comfortable
|
|
49
49
|
* density) are also dropped to keep URLs short and canonical.
|
|
50
50
|
*/
|
|
51
|
-
export declare function searchParamsFromFilters(f:
|
|
51
|
+
export declare function searchParamsFromFilters(f: IndexFilters): URLSearchParams;
|
|
52
52
|
/** True if any filter is active (i.e. the result list isn't "all items"). */
|
|
53
|
-
export declare function hasAnyFilter(f:
|
|
53
|
+
export declare function hasAnyFilter(f: IndexFilters): boolean;
|
|
54
54
|
/** How many items per page. Constant for now; future versions may vary. */
|
|
55
55
|
export declare const PAGE_SIZE = 20;
|
|
56
|
-
export declare function applySort(items: IndexRecord[], sort:
|
|
56
|
+
export declare function applySort(items: IndexRecord[], sort: IndexSort): IndexRecord[];
|
|
57
57
|
/** Slice an array for a given page (1-based). */
|
|
58
58
|
export declare function paginate<T>(items: T[], page: number, pageSize?: number): T[];
|
|
59
59
|
/** Total number of pages given an item count. Always >= 1. */
|
|
60
60
|
export declare function totalPages(itemCount: number, pageSize?: number): number;
|
|
61
61
|
/** Resolve the effective sort from a filters object, applying default. */
|
|
62
|
-
export declare function effectiveSort(f:
|
|
62
|
+
export declare function effectiveSort(f: IndexFilters): IndexSort;
|
|
63
63
|
/** Resolve the effective page from a filters object, applying default. */
|
|
64
|
-
export declare function effectivePage(f:
|
|
64
|
+
export declare function effectivePage(f: IndexFilters): number;
|
|
65
65
|
/**
|
|
66
66
|
* Return the subset of items that match all active filters (AND across
|
|
67
67
|
* dimensions, OR within a dimension).
|
|
@@ -69,10 +69,10 @@ export declare function effectivePage(f: ItemsFilters): number;
|
|
|
69
69
|
* `q` is a case-insensitive substring search across name, owner,
|
|
70
70
|
* description, and category. Other dimensions are exact match.
|
|
71
71
|
*/
|
|
72
|
-
export declare function
|
|
72
|
+
export declare function filterRecords(items: IndexRecord[], f: IndexFilters): IndexRecord[];
|
|
73
73
|
/** Build a flat list of "active filter" chips for display + removal. */
|
|
74
|
-
export declare function activeFilterChips(f:
|
|
75
|
-
key: keyof
|
|
74
|
+
export declare function activeFilterChips(f: IndexFilters): {
|
|
75
|
+
key: keyof IndexFilters;
|
|
76
76
|
value: string;
|
|
77
77
|
label: string;
|
|
78
78
|
}[];
|
|
@@ -84,7 +84,7 @@ export declare function activeFilterChips(f: ItemsFilters): {
|
|
|
84
84
|
* Also resets page to 1 so the user doesn't get stranded on a high page
|
|
85
85
|
* that no longer has results.
|
|
86
86
|
*/
|
|
87
|
-
export declare function removeFilter(f:
|
|
87
|
+
export declare function removeFilter(f: IndexFilters, key: keyof IndexFilters, value: string): IndexFilters;
|
|
88
88
|
/**
|
|
89
89
|
* Build the full list of facet values from the items array, preserving
|
|
90
90
|
* a sensible order (frequency desc, then alphabetical for ties).
|
|
@@ -111,7 +111,4 @@ export declare function buildFacets(items: IndexRecord[]): {
|
|
|
111
111
|
count: number;
|
|
112
112
|
}[];
|
|
113
113
|
};
|
|
114
|
-
export declare const filterApps: typeof filterItems;
|
|
115
|
-
export type AppsFilters = ItemsFilters;
|
|
116
|
-
export type AppsSort = ItemsSort;
|
|
117
114
|
//# sourceMappingURL=search.d.ts.map
|
package/dist/lib/search.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/lib/search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGnD;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,8EAA8E;IAC9E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,2BAA2B;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,0CAA0C;AAC1C,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;EAMf,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC;AAmB/D;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,eAAe,GAAG,YAAY,CAsBzE;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,YAAY,GAAG,eAAe,CAaxE;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,CAAC,EAAE,YAAY,GAAG,OAAO,CAWrD;AAED,2EAA2E;AAC3E,eAAO,MAAM,SAAS,KAAoB,CAAC;AAyB3C,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,SAAS,GAAG,WAAW,EAAE,CA8B9E;AAED,iDAAiD;AACjD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,SAAY,GAAG,CAAC,EAAE,CAG/E;AAED,8DAA8D;AAC9D,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,SAAY,GAAG,MAAM,CAE1E;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,CAAC,EAAE,YAAY,GAAG,SAAS,CAExD;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,CAErD;AAED;;;;;;GAMG;AACH,wBAAgB,
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/lib/search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGnD;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,8EAA8E;IAC9E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,2BAA2B;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,0CAA0C;AAC1C,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;EAMf,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC;AAmB/D;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,eAAe,GAAG,YAAY,CAsBzE;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,YAAY,GAAG,eAAe,CAaxE;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,CAAC,EAAE,YAAY,GAAG,OAAO,CAWrD;AAED,2EAA2E;AAC3E,eAAO,MAAM,SAAS,KAAoB,CAAC;AAyB3C,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,SAAS,GAAG,WAAW,EAAE,CA8B9E;AAED,iDAAiD;AACjD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,SAAY,GAAG,CAAC,EAAE,CAG/E;AAED,8DAA8D;AAC9D,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,SAAY,GAAG,MAAM,CAE1E;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,CAAC,EAAE,YAAY,GAAG,SAAS,CAExD;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,CAErD;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,CAAC,EAAE,YAAY,GAAG,WAAW,EAAE,CA8FlF;AAED,wEAAwE;AACxE,wBAAgB,iBAAiB,CAC/B,CAAC,EAAE,YAAY,GACd;IAAE,GAAG,EAAE,MAAM,YAAY,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CAqC7D;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,CAAC,EAAE,YAAY,EACf,GAAG,EAAE,MAAM,YAAY,EACvB,KAAK,EAAE,MAAM,GACZ,YAAY,CAYd;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;;EAgC/C"}
|
package/dist/lib/search.js
CHANGED
|
@@ -170,7 +170,7 @@ export function effectivePage(f) {
|
|
|
170
170
|
* `q` is a case-insensitive substring search across name, owner,
|
|
171
171
|
* description, and category. Other dimensions are exact match.
|
|
172
172
|
*/
|
|
173
|
-
export function
|
|
173
|
+
export function filterRecords(items, f) {
|
|
174
174
|
const q = f.q?.trim().toLowerCase();
|
|
175
175
|
const stacks = f.stacks?.length ? new Set(f.stacks) : null;
|
|
176
176
|
const platforms = f.platforms?.length ? new Set(f.platforms) : null;
|
|
@@ -361,12 +361,9 @@ export function buildFacets(items) {
|
|
|
361
361
|
licenses: sortByCountThenName(counts.license),
|
|
362
362
|
};
|
|
363
363
|
}
|
|
364
|
-
// ── V1-published API
|
|
365
|
-
//
|
|
366
|
-
//
|
|
367
|
-
//
|
|
368
|
-
//
|
|
369
|
-
// template's `apps/index.astro` (built against the published API)
|
|
370
|
-
// also works against the local workspace source.
|
|
371
|
-
export const filterApps = filterItems;
|
|
364
|
+
// ── V1-published API ─────────────────────────────────────────────────
|
|
365
|
+
// `IndexFilters` / `IndexSort` are the canonical V1 names for the
|
|
366
|
+
// filter-state type. The internal functions (filterRecords, applySort,
|
|
367
|
+
// paginate, buildFacets, etc.) operate on the generic `IndexRecord`
|
|
368
|
+
// shape and are intentionally framework-agnostic.
|
|
372
369
|
//# sourceMappingURL=search.js.map
|
package/dist/lib/search.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/lib/search.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/lib/search.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@grove-dev/astro",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.14",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Astro framework adapter for Grove. Components, layouts, design tokens, and a default template.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
"./layouts/*": "./src/layouts/*.astro"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@grove-dev/core": "0.2.
|
|
47
|
-
"@grove-dev/ui": "1.0.
|
|
46
|
+
"@grove-dev/core": "0.2.14",
|
|
47
|
+
"@grove-dev/ui": "1.0.4",
|
|
48
48
|
"astro": "^6.4.6"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* RecordSection — generic lens-style section wrapper for the
|
|
4
4
|
* home page.
|
|
5
5
|
*
|
|
6
|
-
* Renders a SectionHeader + a 3-column grid of `ItemCard`s
|
|
6
|
+
* Renders a SectionHeader + a 3-column grid of `ItemCard`s (a
|
|
7
|
+
* record card; kept as `ItemCard` for V1 published API stability),
|
|
7
8
|
* optional "View all" link in the header. Generic: takes any
|
|
8
9
|
* `IndexRecord[]` (the slim list-page shape, discriminated union
|
|
9
10
|
* over `kind`).
|
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
* repeated key. Empty values are dropped, so the URL stays clean.
|
|
12
12
|
*
|
|
13
13
|
* Generic: takes a `facets` map of `{ value, label, count }[]` per
|
|
14
|
-
* dimension and an `initial` `
|
|
14
|
+
* dimension and an `initial` `IndexFilters` for preselecting the
|
|
15
15
|
* current URL state.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
import type {
|
|
18
|
+
import type { IndexFilters } from "../lib/search";
|
|
19
19
|
import { SORT_OPTIONS } from "../lib/search";
|
|
20
20
|
import FilterGroupMenu from "./FilterGroupMenu.astro";
|
|
21
21
|
|
|
@@ -35,7 +35,7 @@ interface Facets {
|
|
|
35
35
|
|
|
36
36
|
interface Props {
|
|
37
37
|
facets: Facets;
|
|
38
|
-
initial:
|
|
38
|
+
initial: IndexFilters;
|
|
39
39
|
pathPrefix?: string;
|
|
40
40
|
class?: string;
|
|
41
41
|
/** Hide specific facets. Default: all shown. */
|
package/src/lib/repo.ts
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* Returns nulls if the URL doesn't match github.com/{owner}/{repo}.
|
|
4
4
|
*
|
|
5
5
|
* Used in:
|
|
6
|
-
* - ItemCard avatar fallback (owner avatar via GitHub avatars
|
|
6
|
+
* - ItemCard avatar fallback (owner avatar via GitHub avatars
|
|
7
|
+
* API; component name retained for V1 published API stability)
|
|
7
8
|
* - App detail page (showing owner + repo name in breadcrumb / header)
|
|
8
9
|
* - Anywhere we need to display "@owner / repo" or link to the owner
|
|
9
10
|
*/
|
package/src/lib/search.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { labelDisplay, lensDisplay, statusDisplay } from "./display.js";
|
|
|
7
7
|
* Multi-value fields use repeated keys in the URL: `?stack=Flutter&stack=React+Native`.
|
|
8
8
|
* Empty / undefined fields mean "no filter on this dimension".
|
|
9
9
|
*/
|
|
10
|
-
export type
|
|
10
|
+
export type IndexFilters = {
|
|
11
11
|
q?: string;
|
|
12
12
|
stacks?: string[];
|
|
13
13
|
platforms?: string[];
|
|
@@ -18,7 +18,7 @@ export type ItemsFilters = {
|
|
|
18
18
|
/** A curated lens (e.g. "good-to-learn", "production-like"). Single value. */
|
|
19
19
|
lens?: string;
|
|
20
20
|
/** Sort order. Single value, defaults to "recently-updated". */
|
|
21
|
-
sort?:
|
|
21
|
+
sort?: IndexSort;
|
|
22
22
|
/** 1-based page number. */
|
|
23
23
|
page?: number;
|
|
24
24
|
};
|
|
@@ -32,9 +32,9 @@ export const SORT_OPTIONS = [
|
|
|
32
32
|
{ value: "alphabetical", label: "Alphabetical" },
|
|
33
33
|
] as const;
|
|
34
34
|
|
|
35
|
-
export type
|
|
35
|
+
export type IndexSort = (typeof SORT_OPTIONS)[number]["value"];
|
|
36
36
|
|
|
37
|
-
const DEFAULT_SORT:
|
|
37
|
+
const DEFAULT_SORT: IndexSort = "recently-updated";
|
|
38
38
|
const DEFAULT_PAGE = 1;
|
|
39
39
|
const DEFAULT_PAGE_SIZE = 20;
|
|
40
40
|
|
|
@@ -55,13 +55,13 @@ const KEYS = {
|
|
|
55
55
|
* Read filters from a URLSearchParams (or anything URLSearchParams-shaped,
|
|
56
56
|
* e.g. the result of `new URL(req.url).searchParams`).
|
|
57
57
|
*/
|
|
58
|
-
export function filtersFromSearchParams(sp: URLSearchParams):
|
|
58
|
+
export function filtersFromSearchParams(sp: URLSearchParams): IndexFilters {
|
|
59
59
|
const rawSort = sp.get(KEYS.sort);
|
|
60
60
|
// Backwards-compat: old "most-mature" sort now maps to "best-overall".
|
|
61
61
|
const normalizedSort = rawSort === "most-mature" ? "best-overall" : rawSort;
|
|
62
|
-
const sort:
|
|
63
|
-
normalizedSort && SORT_OPTIONS.some((o) => o.value === normalizedSort)
|
|
64
|
-
? (normalizedSort as
|
|
62
|
+
const sort: IndexSort | undefined =
|
|
63
|
+
normalizedSort && (SORT_OPTIONS as readonly { value: string }[]).some((o) => o.value === normalizedSort)
|
|
64
|
+
? (normalizedSort as IndexSort)
|
|
65
65
|
: undefined;
|
|
66
66
|
const rawPage = Number(sp.get(KEYS.page));
|
|
67
67
|
const page = Number.isFinite(rawPage) && rawPage >= 1 ? Math.floor(rawPage) : undefined;
|
|
@@ -84,7 +84,7 @@ export function filtersFromSearchParams(sp: URLSearchParams): ItemsFilters {
|
|
|
84
84
|
* Undefined / empty values are dropped. Defaults (sort, page 1, comfortable
|
|
85
85
|
* density) are also dropped to keep URLs short and canonical.
|
|
86
86
|
*/
|
|
87
|
-
export function searchParamsFromFilters(f:
|
|
87
|
+
export function searchParamsFromFilters(f: IndexFilters): URLSearchParams {
|
|
88
88
|
const sp = new URLSearchParams();
|
|
89
89
|
if (f.q) sp.set(KEYS.q, f.q);
|
|
90
90
|
for (const v of f.stacks ?? []) sp.append(KEYS.stacks, v);
|
|
@@ -100,7 +100,7 @@ export function searchParamsFromFilters(f: ItemsFilters): URLSearchParams {
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
/** True if any filter is active (i.e. the result list isn't "all items"). */
|
|
103
|
-
export function hasAnyFilter(f:
|
|
103
|
+
export function hasAnyFilter(f: IndexFilters): boolean {
|
|
104
104
|
if (f.q && f.q.trim()) return true;
|
|
105
105
|
if (f.lens) return true;
|
|
106
106
|
return Boolean(
|
|
@@ -139,7 +139,7 @@ function recordAddedAt(record: IndexRecord): string | null {
|
|
|
139
139
|
return record.curation?.reviewedAt ?? null;
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
-
export function applySort(items: IndexRecord[], sort:
|
|
142
|
+
export function applySort(items: IndexRecord[], sort: IndexSort): IndexRecord[] {
|
|
143
143
|
const arr = items.slice();
|
|
144
144
|
const ts = (s?: string | null): number => (s ? new Date(s).valueOf() : 0);
|
|
145
145
|
switch (sort) {
|
|
@@ -183,12 +183,12 @@ export function totalPages(itemCount: number, pageSize = PAGE_SIZE): number {
|
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
/** Resolve the effective sort from a filters object, applying default. */
|
|
186
|
-
export function effectiveSort(f:
|
|
186
|
+
export function effectiveSort(f: IndexFilters): IndexSort {
|
|
187
187
|
return f.sort ?? DEFAULT_SORT;
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
/** Resolve the effective page from a filters object, applying default. */
|
|
191
|
-
export function effectivePage(f:
|
|
191
|
+
export function effectivePage(f: IndexFilters): number {
|
|
192
192
|
return f.page ?? DEFAULT_PAGE;
|
|
193
193
|
}
|
|
194
194
|
|
|
@@ -199,7 +199,7 @@ export function effectivePage(f: ItemsFilters): number {
|
|
|
199
199
|
* `q` is a case-insensitive substring search across name, owner,
|
|
200
200
|
* description, and category. Other dimensions are exact match.
|
|
201
201
|
*/
|
|
202
|
-
export function
|
|
202
|
+
export function filterRecords(items: IndexRecord[], f: IndexFilters): IndexRecord[] {
|
|
203
203
|
const q = f.q?.trim().toLowerCase();
|
|
204
204
|
const stacks = f.stacks?.length ? new Set(f.stacks) : null;
|
|
205
205
|
const platforms = f.platforms?.length ? new Set(f.platforms) : null;
|
|
@@ -297,9 +297,9 @@ export function filterItems(items: IndexRecord[], f: ItemsFilters): IndexRecord[
|
|
|
297
297
|
|
|
298
298
|
/** Build a flat list of "active filter" chips for display + removal. */
|
|
299
299
|
export function activeFilterChips(
|
|
300
|
-
f:
|
|
301
|
-
): { key: keyof
|
|
302
|
-
const out: { key: keyof
|
|
300
|
+
f: IndexFilters,
|
|
301
|
+
): { key: keyof IndexFilters; value: string; label: string }[] {
|
|
302
|
+
const out: { key: keyof IndexFilters; value: string; label: string }[] = [];
|
|
303
303
|
|
|
304
304
|
if (f.q && f.q.trim()) {
|
|
305
305
|
out.push({ key: "q", value: "", label: `“${f.q}”` });
|
|
@@ -346,11 +346,11 @@ export function activeFilterChips(
|
|
|
346
346
|
* that no longer has results.
|
|
347
347
|
*/
|
|
348
348
|
export function removeFilter(
|
|
349
|
-
f:
|
|
350
|
-
key: keyof
|
|
349
|
+
f: IndexFilters,
|
|
350
|
+
key: keyof IndexFilters,
|
|
351
351
|
value: string,
|
|
352
|
-
):
|
|
353
|
-
let next:
|
|
352
|
+
): IndexFilters {
|
|
353
|
+
let next: IndexFilters;
|
|
354
354
|
if (key === "q") {
|
|
355
355
|
next = { ...f, q: undefined };
|
|
356
356
|
} else {
|
|
@@ -401,13 +401,8 @@ export function buildFacets(items: IndexRecord[]) {
|
|
|
401
401
|
};
|
|
402
402
|
}
|
|
403
403
|
|
|
404
|
-
// ── V1-published API
|
|
405
|
-
//
|
|
406
|
-
//
|
|
407
|
-
//
|
|
408
|
-
//
|
|
409
|
-
// template's `apps/index.astro` (built against the published API)
|
|
410
|
-
// also works against the local workspace source.
|
|
411
|
-
export const filterApps = filterItems;
|
|
412
|
-
export type AppsFilters = ItemsFilters;
|
|
413
|
-
export type AppsSort = ItemsSort;
|
|
404
|
+
// ── V1-published API ─────────────────────────────────────────────────
|
|
405
|
+
// `IndexFilters` / `IndexSort` are the canonical V1 names for the
|
|
406
|
+
// filter-state type. The internal functions (filterRecords, applySort,
|
|
407
|
+
// paginate, buildFacets, etc.) operate on the generic `IndexRecord`
|
|
408
|
+
// shape and are intentionally framework-agnostic.
|
package/src/styles.css
CHANGED
|
@@ -513,7 +513,8 @@
|
|
|
513
513
|
* names (`card`, `btn-primary`, `btn-outline`, `btn-ghost`). New
|
|
514
514
|
* components should use the `grove-` prefix. These rules mirror
|
|
515
515
|
* the `grove-*` definitions above so the openapps-derived
|
|
516
|
-
* components (ItemCard, AppCard, etc.
|
|
516
|
+
* components (ItemCard, AppCard, etc. — kept as `ItemCard` for V1
|
|
517
|
+
* published API stability) work without per-component
|
|
517
518
|
* edits.
|
|
518
519
|
* ────────────────────────────────────────────────────────────────────*/
|
|
519
520
|
.card {
|
|
@@ -539,6 +540,7 @@
|
|
|
539
540
|
|
|
540
541
|
/* Chip — small inline label used for platforms/stacks/etc. on
|
|
541
542
|
* ItemCard. Mirrors openapps' `.chip` from the ItemCard.astro
|
|
543
|
+
* (component name retained for V1 published API stability).
|
|
542
544
|
* `<style>` block so the @apply in the component still works. */
|
|
543
545
|
.chip {
|
|
544
546
|
display: inline-flex;
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@astrojs/check": "^0.9.9",
|
|
28
|
-
"@grove-dev/astro": "0.2.
|
|
29
|
-
"@grove-dev/cli": "0.2.
|
|
30
|
-
"@grove-dev/core": "0.2.
|
|
28
|
+
"@grove-dev/astro": "0.2.14",
|
|
29
|
+
"@grove-dev/cli": "0.2.14",
|
|
30
|
+
"@grove-dev/core": "0.2.14",
|
|
31
31
|
"@tailwindcss/vite": "^4.3.0",
|
|
32
32
|
"astro": "^6.4.4",
|
|
33
33
|
"marked": "^18.0.0",
|
|
@@ -2,61 +2,61 @@
|
|
|
2
2
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
3
3
|
<url>
|
|
4
4
|
<loc>https://example.com/</loc>
|
|
5
|
-
<lastmod>2026-06-
|
|
5
|
+
<lastmod>2026-06-13T15:14:22.098Z</lastmod>
|
|
6
6
|
<changefreq>daily</changefreq>
|
|
7
7
|
<priority>1.0</priority>
|
|
8
8
|
</url>
|
|
9
9
|
<url>
|
|
10
10
|
<loc>https://example.com/projects</loc>
|
|
11
|
-
<lastmod>2026-06-
|
|
11
|
+
<lastmod>2026-06-13T15:14:22.098Z</lastmod>
|
|
12
12
|
<changefreq>daily</changefreq>
|
|
13
13
|
<priority>0.9</priority>
|
|
14
14
|
</url>
|
|
15
15
|
<url>
|
|
16
16
|
<loc>https://example.com/projects/coolify</loc>
|
|
17
|
-
<lastmod>2026-06-
|
|
17
|
+
<lastmod>2026-06-13T15:14:22.098Z</lastmod>
|
|
18
18
|
<changefreq>weekly</changefreq>
|
|
19
19
|
<priority>0.7</priority>
|
|
20
20
|
</url>
|
|
21
21
|
<url>
|
|
22
22
|
<loc>https://example.com/projects/gitea</loc>
|
|
23
|
-
<lastmod>2026-06-
|
|
23
|
+
<lastmod>2026-06-13T15:14:22.098Z</lastmod>
|
|
24
24
|
<changefreq>weekly</changefreq>
|
|
25
25
|
<priority>0.7</priority>
|
|
26
26
|
</url>
|
|
27
27
|
<url>
|
|
28
28
|
<loc>https://example.com/projects/hoppscotch</loc>
|
|
29
|
-
<lastmod>2026-06-
|
|
29
|
+
<lastmod>2026-06-13T15:14:22.098Z</lastmod>
|
|
30
30
|
<changefreq>weekly</changefreq>
|
|
31
31
|
<priority>0.7</priority>
|
|
32
32
|
</url>
|
|
33
33
|
<url>
|
|
34
34
|
<loc>https://example.com/projects/inventree</loc>
|
|
35
|
-
<lastmod>2026-06-
|
|
35
|
+
<lastmod>2026-06-13T15:14:22.098Z</lastmod>
|
|
36
36
|
<changefreq>weekly</changefreq>
|
|
37
37
|
<priority>0.7</priority>
|
|
38
38
|
</url>
|
|
39
39
|
<url>
|
|
40
40
|
<loc>https://example.com/projects/label-studio</loc>
|
|
41
|
-
<lastmod>2026-06-
|
|
41
|
+
<lastmod>2026-06-13T15:14:22.098Z</lastmod>
|
|
42
42
|
<changefreq>weekly</changefreq>
|
|
43
43
|
<priority>0.7</priority>
|
|
44
44
|
</url>
|
|
45
45
|
<url>
|
|
46
46
|
<loc>https://example.com/projects/logseq</loc>
|
|
47
|
-
<lastmod>2026-06-
|
|
47
|
+
<lastmod>2026-06-13T15:14:22.098Z</lastmod>
|
|
48
48
|
<changefreq>weekly</changefreq>
|
|
49
49
|
<priority>0.7</priority>
|
|
50
50
|
</url>
|
|
51
51
|
<url>
|
|
52
52
|
<loc>https://example.com/projects/private-gpt</loc>
|
|
53
|
-
<lastmod>2026-06-
|
|
53
|
+
<lastmod>2026-06-13T15:14:22.098Z</lastmod>
|
|
54
54
|
<changefreq>weekly</changefreq>
|
|
55
55
|
<priority>0.7</priority>
|
|
56
56
|
</url>
|
|
57
57
|
<url>
|
|
58
58
|
<loc>https://example.com/projects/wakapi</loc>
|
|
59
|
-
<lastmod>2026-06-
|
|
59
|
+
<lastmod>2026-06-13T15:14:22.098Z</lastmod>
|
|
60
60
|
<changefreq>weekly</changefreq>
|
|
61
61
|
<priority>0.7</priority>
|
|
62
62
|
</url>
|
|
@@ -67,6 +67,9 @@ interface SiteConfigPayload {
|
|
|
67
67
|
kind?: "project" | "resource" | "entity";
|
|
68
68
|
routeSlug?: string;
|
|
69
69
|
itemSlug?: string;
|
|
70
|
+
/** V1 canonical field name for the record detail slug
|
|
71
|
+
* (replaces the V0 `itemSlug` field). */
|
|
72
|
+
recordSlug?: string;
|
|
70
73
|
labelSingular?: string;
|
|
71
74
|
labelPlural?: string;
|
|
72
75
|
};
|
|
@@ -226,10 +229,11 @@ export function indexSlug(): string {
|
|
|
226
229
|
return blueprintConfig.routeSlug ?? "projects";
|
|
227
230
|
}
|
|
228
231
|
|
|
229
|
-
/** URL slug for a single
|
|
230
|
-
* `[
|
|
231
|
-
|
|
232
|
-
|
|
232
|
+
/** URL slug for a single record detail page (the dynamic
|
|
233
|
+
* `[recordSlug]` segment). Default "project" for backwards-compat
|
|
234
|
+
* with V0-published configs that exposed the field as `itemSlug`. */
|
|
235
|
+
export function recordSlugConfig(): string {
|
|
236
|
+
return blueprintConfig.recordSlug ?? blueprintConfig.itemSlug ?? "project";
|
|
233
237
|
}
|
|
234
238
|
|
|
235
239
|
/** Singular human label, e.g. "project", "resource", "entity". */
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* Generic across the 3 record kinds (project / resource / entity) —
|
|
18
18
|
* non-project fields simply render nothing. The URL is dynamic on
|
|
19
19
|
* both `[slug]` (blueprint route, e.g. `projects`/`resources`/
|
|
20
|
-
* `entities`) and `[
|
|
20
|
+
* `entities`) and `[recordSlug]` (the record slug), so a single page
|
|
21
21
|
* file serves every blueprint and every record.
|
|
22
22
|
*/
|
|
23
23
|
import siteConfig from "../../../data/generated/site-config.json";
|
|
@@ -54,12 +54,12 @@ export async function getStaticPaths() {
|
|
|
54
54
|
/* not present */
|
|
55
55
|
}
|
|
56
56
|
return fullRecords.map((record) => ({
|
|
57
|
-
params: { slug: dirSlug,
|
|
57
|
+
params: { slug: dirSlug, recordSlug: record.slug },
|
|
58
58
|
}));
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
const slug = Astro.params.slug ?? indexSlug();
|
|
62
|
-
const recordSlug = Astro.params.
|
|
62
|
+
const recordSlug = Astro.params.recordSlug ?? "";
|
|
63
63
|
const project = projectBySlug(recordSlug);
|
|
64
64
|
const resource = resourceBySlug(recordSlug);
|
|
65
65
|
const entity = entityBySlug(recordSlug);
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* Mirrors the openapps list structure:
|
|
6
6
|
* - SmartLensTabs (All / Trending / Recently added / Established / Featured)
|
|
7
7
|
* - RefinePanel (Stack / Platform / Category / License / Sort)
|
|
8
|
-
* -
|
|
8
|
+
* - RecordSection rows (full record cards; the `ItemSection` V0
|
|
9
|
+
* name was renamed to `RecordSection` in V1)
|
|
9
10
|
* - ExploreByCategory / ExploreByStack (compact pill lists)
|
|
10
11
|
*
|
|
11
12
|
* Generic: the URL slug (e.g. `/projects/`, `/resources/`,
|
|
@@ -15,11 +16,11 @@
|
|
|
15
16
|
*/
|
|
16
17
|
import siteConfig from "../../../data/generated/site-config.json";
|
|
17
18
|
import { items, itemLabel, itemLabelPlural } from "../../data/records";
|
|
18
|
-
import type {
|
|
19
|
+
import type { IndexFilters } from "@grove-dev/astro";
|
|
19
20
|
import BaseLayout from "@grove-dev/astro/layouts/BaseLayout.astro";
|
|
20
21
|
import SmartLensTabs from "@grove-dev/astro/components/SmartLensTabs.astro";
|
|
21
22
|
import RefinePanel from "@grove-dev/astro/components/RefinePanel.astro";
|
|
22
|
-
import
|
|
23
|
+
import IndexRow from "@grove-dev/astro/components/IndexRow.astro";
|
|
23
24
|
import ExploreByCategory from "@grove-dev/astro/components/ExploreByCategory.astro";
|
|
24
25
|
import ExploreByStack from "@grove-dev/astro/components/ExploreByStack.astro";
|
|
25
26
|
import {
|
|
@@ -30,7 +31,7 @@ import {
|
|
|
30
31
|
countByStack,
|
|
31
32
|
effectivePage,
|
|
32
33
|
effectiveSort,
|
|
33
|
-
|
|
34
|
+
filterRecords,
|
|
34
35
|
filtersFromSearchParams,
|
|
35
36
|
paginate,
|
|
36
37
|
searchParamsFromFilters,
|
|
@@ -57,7 +58,7 @@ const filters = filtersFromSearchParams(Astro.url.searchParams);
|
|
|
57
58
|
const facets = buildFacets(items);
|
|
58
59
|
const sort = effectiveSort(filters);
|
|
59
60
|
const requestedPage = effectivePage(filters);
|
|
60
|
-
const filtered =
|
|
61
|
+
const filtered = filterRecords(items, filters);
|
|
61
62
|
const sorted = applySort(filtered, sort);
|
|
62
63
|
const pages = totalPages(sorted.length);
|
|
63
64
|
const page = Math.min(requestedPage, pages);
|
|
@@ -106,15 +107,15 @@ const stackEntries = [...countByStack(items as Parameters<typeof countByStack>[0
|
|
|
106
107
|
.map(([name, count]) => ({ name, slug: name, count }));
|
|
107
108
|
|
|
108
109
|
function hrefForPage(target: number): string {
|
|
109
|
-
const next:
|
|
110
|
+
const next: IndexFilters = { ...filters, page: target };
|
|
110
111
|
const query = searchParamsFromFilters(next).toString();
|
|
111
112
|
return query ? `/${slug}?${query}` : `/${slug}`;
|
|
112
113
|
}
|
|
113
114
|
|
|
114
|
-
function hrefForRemove(key: keyof
|
|
115
|
-
const params = new URLSearchParams(
|
|
116
|
-
|
|
117
|
-
const urlKey: Partial<Record<keyof
|
|
115
|
+
function hrefForRemove(key: keyof IndexFilters, value: string): string {
|
|
116
|
+
const params = new URLSearchParams();
|
|
117
|
+
const next: IndexFilters = { ...filters, page: 1 };
|
|
118
|
+
const urlKey: Partial<Record<keyof IndexFilters, string>> = {
|
|
118
119
|
stacks: "stack",
|
|
119
120
|
platforms: "platform",
|
|
120
121
|
categories: "category",
|
|
@@ -266,8 +267,8 @@ function hrefForRemove(key: keyof AppsFilters, value: string): string {
|
|
|
266
267
|
|
|
267
268
|
<ul id="results-list" class="m-0 flex list-none flex-col gap-3 p-0">
|
|
268
269
|
{sorted.map((item) => (
|
|
269
|
-
<li class="m-0 p-0" data-
|
|
270
|
-
<
|
|
270
|
+
<li class="m-0 p-0" data-record-slug={item.slug}>
|
|
271
|
+
<IndexRow record={item as Parameters<typeof IndexRow>[0]["record"]} detailHref={`/${slug}/${item.slug}`} />
|
|
271
272
|
</li>
|
|
272
273
|
))}
|
|
273
274
|
</ul>
|
|
@@ -369,11 +370,11 @@ function hrefForRemove(key: keyof AppsFilters, value: string): string {
|
|
|
369
370
|
var order = new Map(filtered.map(function (item, index) { return [item.slug, index]; }));
|
|
370
371
|
Array.from(list.children)
|
|
371
372
|
.sort(function (a, b) {
|
|
372
|
-
return (order.get(a.dataset.
|
|
373
|
-
(order.get(b.dataset.
|
|
373
|
+
return (order.get(a.dataset.recordSlug) ?? Number.MAX_SAFE_INTEGER) -
|
|
374
|
+
(order.get(b.dataset.recordSlug) ?? Number.MAX_SAFE_INTEGER);
|
|
374
375
|
})
|
|
375
376
|
.forEach(function (node) {
|
|
376
|
-
node.hidden = !visible.has(node.dataset.
|
|
377
|
+
node.hidden = !visible.has(node.dataset.recordSlug);
|
|
377
378
|
list.appendChild(node);
|
|
378
379
|
});
|
|
379
380
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
/**
|
|
3
|
+
* /apps/<slug> — V0-published alias URL → V1 canonical.
|
|
4
|
+
*
|
|
5
|
+
* The canonical V1 detail URL is `/<blueprint>/<recordSlug>` (e.g.
|
|
6
|
+
* `/projects/coolify`). The V0 published Astro template exposed
|
|
7
|
+
* `/apps/<slug>` as a static alias to keep the openapps-style URL
|
|
8
|
+
* working for project-directory blueprints. Now that the V1
|
|
9
|
+
* template uses the blueprint-aware dynamic route everywhere,
|
|
10
|
+
* this page is a pure redirect: any `/apps/<slug>` request is
|
|
11
|
+
* sent to the blueprint-canonical path.
|
|
12
|
+
*/
|
|
13
|
+
import { indexSlug, fullRecords, projectBySlug, recordBySlug } from "../../data/records";
|
|
14
|
+
|
|
15
|
+
export async function getStaticPaths() {
|
|
16
|
+
return fullRecords.map((r) => ({ params: { recordSlug: r.slug } }));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const slug = indexSlug();
|
|
20
|
+
const recordSlug = Astro.params.recordSlug ?? "";
|
|
21
|
+
|
|
22
|
+
if (slug !== "projects") {
|
|
23
|
+
return Astro.redirect(`/${slug}/${recordSlug}`);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const record = recordBySlug(recordSlug);
|
|
27
|
+
if (!record) {
|
|
28
|
+
return Astro.redirect(`/${slug}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Canonical V1 URL.
|
|
32
|
+
return Astro.redirect(`/${slug}/${recordSlug}`, 301);
|
|
33
|
+
---
|
|
@@ -1,301 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
/**
|
|
3
|
-
* /apps/<slug> — alternate detail URL.
|
|
4
|
-
*
|
|
5
|
-
* Mirrors `/[slug]/[itemSlug].astro` (the blueprint-aware dynamic
|
|
6
|
-
* detail page) at a static URL. For non-project blueprints
|
|
7
|
-
* (resource-hub, ecosystem-map), redirect to the matching dynamic
|
|
8
|
-
* route.
|
|
9
|
-
*/
|
|
10
|
-
import { indexSlug, fullRecords, projectBySlug, recordBySlug } from "../../data/records";
|
|
11
|
-
import BaseLayout from "@grove-dev/astro/layouts/BaseLayout.astro";
|
|
12
|
-
import Icon from "@grove-dev/astro/components/Icon.astro";
|
|
13
|
-
import ScoreBars from "@grove-dev/astro/components/ScoreBars.astro";
|
|
14
|
-
import siteConfig from "../../../data/generated/site-config.json";
|
|
15
|
-
import { getOwnerAndRepoFromRepoUrl, getOwnerAvatarUrl, formatRelative, formatStars, statusDisplay, prettySlug, labelDisplay } from "@grove-dev/astro";
|
|
16
|
-
|
|
17
|
-
export async function getStaticPaths() {
|
|
18
|
-
return fullRecords.map((r) => ({ params: { itemSlug: r.slug } }));
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const slug = indexSlug();
|
|
22
|
-
const itemSlug = Astro.params.itemSlug ?? "";
|
|
23
|
-
|
|
24
|
-
if (slug !== "projects") {
|
|
25
|
-
return Astro.redirect(`/${slug}/${itemSlug}`);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const record = recordBySlug(itemSlug);
|
|
29
|
-
if (!record) {
|
|
30
|
-
return Astro.redirect("/apps");
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const project = projectBySlug(itemSlug);
|
|
34
|
-
const isProject = record.kind === "project";
|
|
35
|
-
const name = record.kind === "resource" ? record.title : record.name;
|
|
36
|
-
const repoUrl = project?.repoUrl ?? (record.links as { github?: string } | undefined)?.github ?? "";
|
|
37
|
-
const homepageUrl = record.links?.website ?? "";
|
|
38
|
-
const logoUrl = project?.logoUrl;
|
|
39
|
-
const stacks = project?.stacks ?? (project?.stack ? [project.stack] : []);
|
|
40
|
-
const platforms = project?.platforms ?? [];
|
|
41
|
-
const github = project?.github?.repository;
|
|
42
|
-
const stars = github?.stargazers_count ?? 0;
|
|
43
|
-
const starsLabel = formatStars(stars);
|
|
44
|
-
const pushedAt = github?.pushed_at ?? null;
|
|
45
|
-
const pushedLabel = formatRelative(pushedAt);
|
|
46
|
-
const ownerRepo = repoUrl ? getOwnerAndRepoFromRepoUrl(repoUrl) : null;
|
|
47
|
-
const avatarSrc = logoUrl ?? (ownerRepo ? getOwnerAvatarUrl(ownerRepo.owner, 80) : null);
|
|
48
|
-
const initials = (name || "").replace(/[^a-z0-9]/gi, "").slice(0, 2).toUpperCase();
|
|
49
|
-
const bestFor = project?.bestFor ?? [];
|
|
50
|
-
const whyListed = project?.whyListed ?? [];
|
|
51
|
-
const caveats = project?.caveats ?? [];
|
|
52
|
-
const distribution = project?.distribution?.channels ?? [];
|
|
53
|
-
const scores = project?.scores ?? null;
|
|
54
|
-
const curationLabels = record.curation?.labels ?? [];
|
|
55
|
-
const tags = record.tags ?? [];
|
|
56
|
-
const healthStatus = project?.health?.status;
|
|
57
|
-
const healthLabel = healthStatus ? statusDisplay(healthStatus) : null;
|
|
58
|
-
|
|
59
|
-
const title = `${name} — ${siteConfig.name}`;
|
|
60
|
-
const description = record.description ?? `${name} on ${siteConfig.name}`;
|
|
61
|
-
|
|
62
|
-
const jsonLd: Record<string, unknown> | null = project
|
|
63
|
-
? {
|
|
64
|
-
"@context": "https://schema.org",
|
|
65
|
-
"@type": "SoftwareSourceCode",
|
|
66
|
-
name,
|
|
67
|
-
description: record.description ?? undefined,
|
|
68
|
-
url: repoUrl || homepageUrl || undefined,
|
|
69
|
-
codeRepository: repoUrl || undefined,
|
|
70
|
-
programmingLanguage: github?.language ?? undefined,
|
|
71
|
-
license: github?.license?.spdx_id ?? undefined,
|
|
72
|
-
author: ownerRepo
|
|
73
|
-
? { "@type": "Organization", name: ownerRepo.owner, url: `https://github.com/${ownerRepo.owner}` }
|
|
74
|
-
: undefined,
|
|
75
|
-
}
|
|
76
|
-
: null;
|
|
77
|
-
---
|
|
78
|
-
|
|
79
|
-
<BaseLayout
|
|
80
|
-
title={title}
|
|
81
|
-
description={description}
|
|
82
|
-
site={siteConfig}
|
|
83
|
-
type="article"
|
|
84
|
-
jsonLd={jsonLd ?? undefined}
|
|
85
|
-
submitHref="/submit"
|
|
86
|
-
submitLabel={`Submit ${name}`}
|
|
87
|
-
>
|
|
88
|
-
<article class="grove-section">
|
|
89
|
-
<div class="grove-container-wide mx-auto px-5 sm:px-7">
|
|
90
|
-
<nav class="mb-6 text-2xs text-ink-500 dark:text-ink-400" aria-label="Breadcrumb">
|
|
91
|
-
<a href="/apps" class="hover:text-ink-900 dark:hover:text-ink-100">Apps</a>
|
|
92
|
-
<span class="mx-1.5 text-ink-300 dark:text-ink-700">/</span>
|
|
93
|
-
<span class="text-ink-700 dark:text-ink-300">{name}</span>
|
|
94
|
-
</nav>
|
|
95
|
-
|
|
96
|
-
<header class="grove-card flex flex-col gap-5 p-6 sm:flex-row sm:items-start">
|
|
97
|
-
<div class="flex-shrink-0">
|
|
98
|
-
{avatarSrc ? (
|
|
99
|
-
<img
|
|
100
|
-
src={avatarSrc}
|
|
101
|
-
alt=""
|
|
102
|
-
width="64"
|
|
103
|
-
height="64"
|
|
104
|
-
loading="lazy"
|
|
105
|
-
decoding="async"
|
|
106
|
-
class="h-16 w-16 rounded-lg border border-ink-200 object-contain bg-white p-1 dark:border-ink-800 dark:bg-ink-950"
|
|
107
|
-
/>
|
|
108
|
-
) : (
|
|
109
|
-
<span
|
|
110
|
-
aria-hidden="true"
|
|
111
|
-
class="inline-flex h-16 w-16 items-center justify-center rounded-lg border border-ink-200 bg-ink-50 text-2xl font-semibold text-ink-700 dark:border-ink-800 dark:bg-ink-900 dark:text-ink-200"
|
|
112
|
-
>
|
|
113
|
-
{initials || "·"}
|
|
114
|
-
</span>
|
|
115
|
-
)}
|
|
116
|
-
</div>
|
|
117
|
-
|
|
118
|
-
<div class="min-w-0 flex-1">
|
|
119
|
-
<div class="flex flex-wrap items-center gap-2">
|
|
120
|
-
<span class="rounded-full border border-ink-200 px-2 py-0.5 text-2xs font-medium uppercase tracking-wider text-ink-700 dark:border-ink-800 dark:text-ink-300">
|
|
121
|
-
{record.kind}
|
|
122
|
-
</span>
|
|
123
|
-
{record.category && (
|
|
124
|
-
<span class="rounded-full border border-ink-200 px-2 py-0.5 text-2xs font-medium text-ink-700 dark:border-ink-800 dark:text-ink-300">
|
|
125
|
-
{record.category}
|
|
126
|
-
</span>
|
|
127
|
-
)}
|
|
128
|
-
{curationLabels.map((l) => (
|
|
129
|
-
<span class="grove-badge" title={`Curated: ${labelDisplay(l) ?? l}`}>
|
|
130
|
-
{labelDisplay(l) ?? prettySlug(l)}
|
|
131
|
-
</span>
|
|
132
|
-
))}
|
|
133
|
-
{healthLabel && (
|
|
134
|
-
<span class="grove-badge grove-badge-stale">{healthLabel}</span>
|
|
135
|
-
)}
|
|
136
|
-
</div>
|
|
137
|
-
|
|
138
|
-
<h1 class="m-0 mt-2 text-[1.75rem] sm:text-[2rem] font-semibold tracking-tight text-ink-900 dark:text-ink-100">
|
|
139
|
-
{name}
|
|
140
|
-
</h1>
|
|
141
|
-
|
|
142
|
-
{ownerRepo && (
|
|
143
|
-
<p class="m-0 mt-1 text-sm text-ink-500 dark:text-ink-400">
|
|
144
|
-
<a
|
|
145
|
-
href={`https://github.com/${ownerRepo.owner}`}
|
|
146
|
-
target="_blank"
|
|
147
|
-
rel="noopener noreferrer"
|
|
148
|
-
class="text-inherit no-underline hover:text-ink-900 dark:hover:text-ink-100"
|
|
149
|
-
>
|
|
150
|
-
@{ownerRepo.owner}
|
|
151
|
-
</a>
|
|
152
|
-
<span class="mx-1 text-ink-300 dark:text-ink-700">/</span>
|
|
153
|
-
<a
|
|
154
|
-
href={repoUrl}
|
|
155
|
-
target="_blank"
|
|
156
|
-
rel="noopener noreferrer"
|
|
157
|
-
class="text-inherit no-underline hover:text-ink-900 dark:hover:text-ink-100"
|
|
158
|
-
>
|
|
159
|
-
{ownerRepo.repo}
|
|
160
|
-
</a>
|
|
161
|
-
</p>
|
|
162
|
-
)}
|
|
163
|
-
|
|
164
|
-
{record.description && (
|
|
165
|
-
<p class="m-0 mt-3 max-w-[68ch] text-base leading-relaxed text-ink-700 dark:text-ink-200">
|
|
166
|
-
{record.description}
|
|
167
|
-
</p>
|
|
168
|
-
)}
|
|
169
|
-
|
|
170
|
-
<div class="mt-5 flex flex-wrap gap-2">
|
|
171
|
-
{repoUrl && (
|
|
172
|
-
<a href={repoUrl} target="_blank" rel="noopener noreferrer" class="grove-btn grove-btn-primary">
|
|
173
|
-
View on GitHub →
|
|
174
|
-
</a>
|
|
175
|
-
)}
|
|
176
|
-
{homepageUrl && (
|
|
177
|
-
<a href={homepageUrl} target="_blank" rel="noopener noreferrer" class="grove-btn grove-btn-outline">
|
|
178
|
-
Homepage
|
|
179
|
-
</a>
|
|
180
|
-
)}
|
|
181
|
-
</div>
|
|
182
|
-
</div>
|
|
183
|
-
</header>
|
|
184
|
-
|
|
185
|
-
{project && (
|
|
186
|
-
<section class="mt-8 grove-card p-6" aria-labelledby="scores-heading">
|
|
187
|
-
<h2 id="scores-heading" class="m-0 text-lg font-semibold tracking-tight text-ink-900 dark:text-ink-100">
|
|
188
|
-
Scores
|
|
189
|
-
</h2>
|
|
190
|
-
<div class="mt-4">
|
|
191
|
-
<ScoreBars scores={scores} />
|
|
192
|
-
</div>
|
|
193
|
-
</section>
|
|
194
|
-
)}
|
|
195
|
-
|
|
196
|
-
{/* BestFor / WhyListed / Caveats grid */}
|
|
197
|
-
{isProject && (bestFor.length > 0 || whyListed.length > 0 || caveats.length > 0) && (
|
|
198
|
-
<section class="mt-8 grid grid-cols-1 gap-4 md:grid-cols-3" aria-label="Curation notes">
|
|
199
|
-
{bestFor.length > 0 && (
|
|
200
|
-
<div class="grove-card p-5">
|
|
201
|
-
<h3 class="m-0 text-sm font-semibold uppercase tracking-wider text-ink-500 dark:text-ink-400">Best for</h3>
|
|
202
|
-
<ul class="mt-3 m-0 flex list-none flex-col gap-1.5 p-0">
|
|
203
|
-
{bestFor.map((b) => <li class="text-sm text-ink-700 dark:text-ink-200">— {b}</li>)}
|
|
204
|
-
</ul>
|
|
205
|
-
</div>
|
|
206
|
-
)}
|
|
207
|
-
{whyListed.length > 0 && (
|
|
208
|
-
<div class="grove-card p-5">
|
|
209
|
-
<h3 class="m-0 text-sm font-semibold uppercase tracking-wider text-ink-500 dark:text-ink-400">Why listed</h3>
|
|
210
|
-
<ul class="mt-3 m-0 flex list-none flex-col gap-1.5 p-0">
|
|
211
|
-
{whyListed.map((w) => <li class="text-sm text-ink-700 dark:text-ink-200">— {w}</li>)}
|
|
212
|
-
</ul>
|
|
213
|
-
</div>
|
|
214
|
-
)}
|
|
215
|
-
{caveats.length > 0 && (
|
|
216
|
-
<div class="grove-card p-5">
|
|
217
|
-
<h3 class="m-0 text-sm font-semibold uppercase tracking-wider text-ink-500 dark:text-ink-400">Caveats</h3>
|
|
218
|
-
<ul class="mt-3 m-0 flex list-none flex-col gap-1.5 p-0">
|
|
219
|
-
{caveats.map((c) => <li class="text-sm text-ink-700 dark:text-ink-200">— {c}</li>)}
|
|
220
|
-
</ul>
|
|
221
|
-
</div>
|
|
222
|
-
)}
|
|
223
|
-
</section>
|
|
224
|
-
)}
|
|
225
|
-
|
|
226
|
-
{/* Stack + Platform chips */}
|
|
227
|
-
{isProject && (stacks.length > 0 || platforms.length > 0) && (
|
|
228
|
-
<section class="mt-8" aria-labelledby="stacks-heading">
|
|
229
|
-
<h2 id="stacks-heading" class="m-0 text-lg font-semibold tracking-tight text-ink-900 dark:text-ink-100">
|
|
230
|
-
Stack & platforms
|
|
231
|
-
</h2>
|
|
232
|
-
<div class="mt-4 flex flex-col gap-3">
|
|
233
|
-
{stacks.length > 0 && (
|
|
234
|
-
<div class="flex flex-wrap items-center gap-2">
|
|
235
|
-
<span class="text-2xs font-medium uppercase tracking-wider text-ink-500 dark:text-ink-400">Stack</span>
|
|
236
|
-
{stacks.map((s) => (
|
|
237
|
-
<span class="grove-badge inline-flex items-center gap-1.5">
|
|
238
|
-
<Icon name={s} category="stack" size={14} />
|
|
239
|
-
{s}
|
|
240
|
-
</span>
|
|
241
|
-
))}
|
|
242
|
-
</div>
|
|
243
|
-
)}
|
|
244
|
-
{platforms.length > 0 && (
|
|
245
|
-
<div class="flex flex-wrap items-center gap-2">
|
|
246
|
-
<span class="text-2xs font-medium uppercase tracking-wider text-ink-500 dark:text-ink-400">Platform</span>
|
|
247
|
-
{platforms.map((p) => (
|
|
248
|
-
<span class="grove-badge inline-flex items-center gap-1.5">
|
|
249
|
-
<Icon name={p} category="platform" size={14} />
|
|
250
|
-
{p}
|
|
251
|
-
</span>
|
|
252
|
-
))}
|
|
253
|
-
</div>
|
|
254
|
-
)}
|
|
255
|
-
</div>
|
|
256
|
-
</section>
|
|
257
|
-
)}
|
|
258
|
-
|
|
259
|
-
{/* Tags */}
|
|
260
|
-
{tags.length > 0 && (
|
|
261
|
-
<section class="mt-8" aria-labelledby="tags-heading">
|
|
262
|
-
<h2 id="tags-heading" class="m-0 text-lg font-semibold tracking-tight text-ink-900 dark:text-ink-100">
|
|
263
|
-
Tags
|
|
264
|
-
</h2>
|
|
265
|
-
<ul class="mt-4 m-0 flex list-none flex-wrap gap-1.5 p-0">
|
|
266
|
-
{tags.map((t) => (
|
|
267
|
-
<li>
|
|
268
|
-
<a href={`/apps?q=${encodeURIComponent(t)}`} class="grove-badge inline-flex items-center gap-1.5">{t}</a>
|
|
269
|
-
</li>
|
|
270
|
-
))}
|
|
271
|
-
</ul>
|
|
272
|
-
</section>
|
|
273
|
-
)}
|
|
274
|
-
|
|
275
|
-
{/* Distribution channels */}
|
|
276
|
-
{distribution.length > 0 && (
|
|
277
|
-
<section class="mt-8" aria-labelledby="dist-heading">
|
|
278
|
-
<h2 id="dist-heading" class="m-0 text-lg font-semibold tracking-tight text-ink-900 dark:text-ink-100">
|
|
279
|
-
Distribution channels
|
|
280
|
-
</h2>
|
|
281
|
-
<ul class="mt-4 m-0 flex list-none flex-col gap-2 p-0">
|
|
282
|
-
{distribution.map((c) => (
|
|
283
|
-
<li class="grove-card flex flex-wrap items-baseline justify-between gap-2 p-3">
|
|
284
|
-
<div class="flex flex-col">
|
|
285
|
-
<span class="text-sm font-semibold text-ink-900 dark:text-ink-100">
|
|
286
|
-
{c.label ?? c.type}
|
|
287
|
-
{c.verified && <span class="ml-2 grove-badge grove-badge-new">Verified</span>}
|
|
288
|
-
</span>
|
|
289
|
-
{c.notes && <span class="text-xs text-ink-500 dark:text-ink-400">{c.notes}</span>}
|
|
290
|
-
</div>
|
|
291
|
-
<a href={c.url} target="_blank" rel="noopener noreferrer" class="grove-btn grove-btn-outline">
|
|
292
|
-
{c.platform ?? c.type} →
|
|
293
|
-
</a>
|
|
294
|
-
</li>
|
|
295
|
-
))}
|
|
296
|
-
</ul>
|
|
297
|
-
</section>
|
|
298
|
-
)}
|
|
299
|
-
</div>
|
|
300
|
-
</article>
|
|
301
|
-
</BaseLayout>
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
/**
|
|
3
|
-
* /apps — alternate list URL.
|
|
4
|
-
*
|
|
5
|
-
* Mirrors `/[slug]/index.astro` (the blueprint-aware dynamic list
|
|
6
|
-
* page) at a static URL so the openapps-style `/apps` route works
|
|
7
|
-
* for project-directory blueprints without per-blueprint forks.
|
|
8
|
-
*
|
|
9
|
-
* For non-project blueprints (resource-hub → /resources,
|
|
10
|
-
* ecosystem-map → /entities), this page redirects to the matching
|
|
11
|
-
* dynamic route.
|
|
12
|
-
*/
|
|
13
|
-
import { indexSlug, itemLabelPlural, items } from "../../data/records";
|
|
14
|
-
import BaseLayout from "@grove-dev/astro/layouts/BaseLayout.astro";
|
|
15
|
-
import SmartLensTabs from "@grove-dev/astro/components/SmartLensTabs.astro";
|
|
16
|
-
import RefinePanel from "@grove-dev/astro/components/RefinePanel.astro";
|
|
17
|
-
import AppsIndexRow from "@grove-dev/astro/components/AppsIndexRow.astro";
|
|
18
|
-
import ExploreByCategory from "@grove-dev/astro/components/ExploreByCategory.astro";
|
|
19
|
-
import ExploreByStack from "@grove-dev/astro/components/ExploreByStack.astro";
|
|
20
|
-
import siteConfig from "../../../data/generated/site-config.json";
|
|
21
|
-
import {
|
|
22
|
-
activeFilterChips,
|
|
23
|
-
applySort,
|
|
24
|
-
buildFacets,
|
|
25
|
-
effectivePage,
|
|
26
|
-
effectiveSort,
|
|
27
|
-
filterApps,
|
|
28
|
-
filtersFromSearchParams,
|
|
29
|
-
paginate,
|
|
30
|
-
totalPages,
|
|
31
|
-
} from "@grove-dev/astro";
|
|
32
|
-
|
|
33
|
-
const slug = indexSlug();
|
|
34
|
-
|
|
35
|
-
// Only render the static /apps route when the active blueprint is
|
|
36
|
-
// project-directory (the openapps-style URL). For other blueprints,
|
|
37
|
-
// redirect to the dynamic `/<slug>/` route.
|
|
38
|
-
if (slug !== "projects") {
|
|
39
|
-
return Astro.redirect(`/${slug}${Astro.url.search}`);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const total = items.length;
|
|
43
|
-
const filters = filtersFromSearchParams(Astro.url.searchParams);
|
|
44
|
-
const facets = buildFacets(items);
|
|
45
|
-
const sort = effectiveSort(filters);
|
|
46
|
-
const requestedPage = effectivePage(filters);
|
|
47
|
-
const filtered = filterApps(items, filters);
|
|
48
|
-
const sorted = applySort(filtered, sort);
|
|
49
|
-
const pages = totalPages(sorted.length);
|
|
50
|
-
const page = Math.min(requestedPage, pages);
|
|
51
|
-
const visibleItems = paginate(sorted, page);
|
|
52
|
-
const chips = activeFilterChips(filters);
|
|
53
|
-
const itemPlural = itemLabelPlural();
|
|
54
|
-
|
|
55
|
-
const title = `${itemPlural.charAt(0).toUpperCase()}${itemPlural.slice(1)} — ${siteConfig.name}`;
|
|
56
|
-
const description = `Browse every curated ${itemPlural.replace(/s$/, "")} in the ${siteConfig.name} directory.`;
|
|
57
|
-
---
|
|
58
|
-
|
|
59
|
-
<BaseLayout title={title} description={description} site={siteConfig}>
|
|
60
|
-
<section class="grove-section">
|
|
61
|
-
<div class="grove-container-wide mx-auto px-5 sm:px-7">
|
|
62
|
-
<header class="mb-6">
|
|
63
|
-
<span class="text-2xs font-medium uppercase tracking-wider text-ink-500 dark:text-ink-400">
|
|
64
|
-
{itemPlural}
|
|
65
|
-
</span>
|
|
66
|
-
<h1 class="m-0 mt-1 text-[1.75rem] sm:text-[2.25rem] font-semibold tracking-tight text-ink-900 dark:text-ink-100">
|
|
67
|
-
Browse the directory
|
|
68
|
-
</h1>
|
|
69
|
-
<p class="m-0 mt-2 max-w-2xl text-base leading-relaxed text-ink-700 dark:text-ink-200">
|
|
70
|
-
Search and filter every curated {itemPlural.replace(/s$/, "")}. Use the
|
|
71
|
-
lens tabs to focus on a curated angle, or refine by stack,
|
|
72
|
-
platform, license, and status.
|
|
73
|
-
</p>
|
|
74
|
-
</header>
|
|
75
|
-
|
|
76
|
-
<div class="mb-6">
|
|
77
|
-
<SmartLensTabs
|
|
78
|
-
currentParams={Astro.url.searchParams}
|
|
79
|
-
pathPrefix="/apps"
|
|
80
|
-
/>
|
|
81
|
-
</div>
|
|
82
|
-
|
|
83
|
-
<div class="mb-8">
|
|
84
|
-
<RefinePanel
|
|
85
|
-
facets={facets}
|
|
86
|
-
initial={filters}
|
|
87
|
-
pathPrefix="/apps"
|
|
88
|
-
/>
|
|
89
|
-
</div>
|
|
90
|
-
|
|
91
|
-
{chips.length > 0 && (
|
|
92
|
-
<ul class="mb-6 flex flex-wrap items-center gap-1.5" aria-label="Active filters">
|
|
93
|
-
{chips.map((chip) => (
|
|
94
|
-
<li>
|
|
95
|
-
<a
|
|
96
|
-
href={chip.removeHref}
|
|
97
|
-
class="grove-badge inline-flex items-center gap-1.5 hover:border-ink-300 dark:hover:border-ink-700"
|
|
98
|
-
title={`Remove filter: ${chip.label}`}
|
|
99
|
-
>
|
|
100
|
-
<span>{chip.label}</span>
|
|
101
|
-
<span aria-hidden="true">×</span>
|
|
102
|
-
</a>
|
|
103
|
-
</li>
|
|
104
|
-
))}
|
|
105
|
-
</ul>
|
|
106
|
-
)}
|
|
107
|
-
|
|
108
|
-
{visibleItems.length === 0 ? (
|
|
109
|
-
<p class="grove-card p-8 text-center text-sm text-ink-500 dark:text-ink-400">
|
|
110
|
-
No {itemPlural} match these filters. Try clearing a filter or two.
|
|
111
|
-
</p>
|
|
112
|
-
) : (
|
|
113
|
-
<ul class="m-0 grid list-none grid-cols-1 gap-3 p-0">
|
|
114
|
-
{visibleItems.map((item) => (
|
|
115
|
-
<li class="m-0 p-0">
|
|
116
|
-
<AppsIndexRow record={item as Parameters<typeof AppsIndexRow>[0]["record"]} detailHref={`/apps/${item.slug}`} />
|
|
117
|
-
</li>
|
|
118
|
-
))}
|
|
119
|
-
</ul>
|
|
120
|
-
)}
|
|
121
|
-
</div>
|
|
122
|
-
</section>
|
|
123
|
-
|
|
124
|
-
<ExploreByCategory
|
|
125
|
-
categories={[
|
|
126
|
-
...new Set(
|
|
127
|
-
items
|
|
128
|
-
.filter((i) => i.kind === "project")
|
|
129
|
-
.map((i) => (i as { category?: string }).category ?? "")
|
|
130
|
-
.filter(Boolean),
|
|
131
|
-
),
|
|
132
|
-
].map((name) => ({ name, slug: name }))}
|
|
133
|
-
pathPrefix="/apps"
|
|
134
|
-
/>
|
|
135
|
-
<ExploreByStack
|
|
136
|
-
stacks={[
|
|
137
|
-
...new Set(
|
|
138
|
-
items
|
|
139
|
-
.filter((i) => i.kind === "project")
|
|
140
|
-
.flatMap((i) => [(i as { stack?: string }).stack ?? "", ...(i as { stacks?: string[] }).stacks])
|
|
141
|
-
.filter(Boolean),
|
|
142
|
-
),
|
|
143
|
-
].map((name) => ({ name, slug: name }))}
|
|
144
|
-
pathPrefix="/apps"
|
|
145
|
-
/>
|
|
146
|
-
</BaseLayout>
|
|
File without changes
|
|
File without changes
|