Skip to content

Commit 00edb02

Browse files
erland-obosalexanbjoscarcarlstrom
authored
Improve component state management and consistency (#1174)
* Rename query and loader to reflect profile context Updated query and loader names from COMPONENTS_INDEX_QUERY to PROFILE_INDEX_QUERY to better align with the context of the profile route. This change avoids duplication of query names in code. * Update component state field to use string with predefined options Replaced the boolean `documentationIsReady` field with a `componentState` string field. Added predefined options (`In progress`, `Ready`, `Deprecated`) and set `In progress` as the default value. This change enhances flexibility and better represents the component's lifecycle. * Add Sanity CLI configuration file Introduce a new CLI configuration file for the Sanity CMS. This file specifies the project ID and dataset to be used, enabling proper setup for CLI operations. * Refactor Sanity types and queries for improved consistency. Simplified type definitions by consolidating union syntax and formatting. Added a new "componentState" field along with its possible values and adjusted the schema to align with these changes. Removed unused "documentationIsReady" field to clean up the types. * Add `state` field to component query and update badge display Included the `state` field in the GROQ query with a default value of "In progress" and replaced conditional badge rendering with dynamic `state` display. This simplifies the handling of component statuses and makes it easier to add new component states later. * Update component schema and queries to include documentation state Added a new "documentationState" field to the component schema with predefined states. Updated all related TypeScript types, GROQ queries, and UI to reflect this change. Adjusted componentState and documentationState options to use consistent casing. * combine documentState, componentState and highlightAsNew * remove unused sanity query * Format --------- Co-authored-by: Alexander Bjerkan <alexander.bjerkan@obos.no> Co-authored-by: Oscar Carlström <oscar.carlstrom@gmail.com>
1 parent 18b0ed8 commit 00edb02

File tree

11 files changed

+248
-174
lines changed

11 files changed

+248
-174
lines changed

apps/docs/app/routes/_docs.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { defineQuery } from 'groq';
1414

1515
const COMPONENTS_NAVIGATION_QUERY = defineQuery(
1616
// make sure the slug is always a string so we don't have add fallback value in code just to make TypeScript happy
17-
`*[_type == "component"]{ _id, name, 'slug': coalesce(slug.current, ''), highlightAsNew} | order(name asc)`,
17+
`*[_type == "component"]{ _id, name, 'slug': coalesce(slug.current, ''), componentState} | order(name asc)`,
1818
);
1919

2020
// This is the shared layout for all the Grunnmuren docs pages that are "public", ie not the Sanity studio

apps/docs/app/routes/_docs/komponenter/$slug.tsx

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,27 @@ import { AnchorHeading } from '@/ui/anchor-heading';
33
import { PropsTable } from '@/ui/props-table';
44
import { ResourceLink, ResourceLinks } from '@/ui/resource-links';
55
import { SanityContent } from '@/ui/sanity-content';
6-
import { Child } from '@obosbbl/grunnmuren-icons-react';
7-
import { Alertbox, Badge, Content } from '@obosbbl/grunnmuren-react';
6+
import { Child, CircusTent } from '@obosbbl/grunnmuren-icons-react';
7+
import { Alertbox, Content } from '@obosbbl/grunnmuren-react';
88
import { createFileRoute, notFound } from '@tanstack/react-router';
99
import type * as props from 'docgen';
1010
import { defineQuery } from 'groq';
1111

1212
const COMPONENT_QUERY = defineQuery(
13-
`*[_type == "component" && slug.current == $slug][0]{ "content": content[] {..., _type == "image-with-caption" => {...,asset->}}, "name": coalesce(name, ''), propsComponents, resourceLinks, highlightAsNew }`,
13+
`*[_type == "component"
14+
&& slug.current == $slug][0]{
15+
"content": content[] {
16+
...,
17+
_type == "image-with-caption" => {
18+
...,
19+
asset->
20+
}
21+
},
22+
"name": coalesce(name, ''),
23+
propsComponents,
24+
resourceLinks,
25+
componentState,
26+
}`,
1427
);
1528

1629
export const Route = createFileRoute('/_docs/komponenter/$slug')({
@@ -43,25 +56,12 @@ function Page() {
4356
<>
4457
<h1 className="heading-l mt-9 mb-4">{data.name}</h1>
4558

46-
<div className="mb-8 flex gap-4">
47-
{data.highlightAsNew && (
48-
<Badge color="mint" size="small">
49-
Ny
50-
</Badge>
51-
)}
52-
{!data.documentationIsReady && (
53-
<Badge color="gray-dark" size="small">
54-
Under arbeid
55-
</Badge>
56-
)}
57-
</div>
58-
5959
<ResourceLinks className="mb-12">
6060
{figmaLink && <ResourceLink type="figma" href={figmaLink} />}
6161
{ghLink && <ResourceLink type="github" href={ghLink} />}
6262
</ResourceLinks>
6363

64-
{data.highlightAsNew && (
64+
{data.componentState === 'new' && (
6565
// biome-ignore lint/a11y/useValidAriaRole: <explanation>
6666
<Alertbox
6767
variant="success"
@@ -70,10 +70,35 @@ function Page() {
7070
role="none"
7171
>
7272
<Content>
73-
Denne komponenten er ny eller har nylig fått større endringer. Ta
74-
den i bruk og kom gjerne med innspill til oss på{' '}
75-
<a href="https://obos.slack.com/archives/C03FR05FJ9F">Slack</a>{' '}
76-
hvordan du synes den fungerer.
73+
<p>
74+
Denne komponenten er ny eller har nylig fått større endringer.
75+
</p>
76+
<p>
77+
Ta den i bruk og kom gjerne med innspill til oss på{' '}
78+
<a href="https://obos.slack.com/archives/C03FR05FJ9F">Slack</a>{' '}
79+
hvordan du synes den fungerer.
80+
</p>
81+
</Content>
82+
</Alertbox>
83+
)}
84+
85+
{data.componentState === 'beta' && (
86+
// biome-ignore lint/a11y/useValidAriaRole: <explanation>
87+
<Alertbox
88+
variant="warning"
89+
className="mb-12 w-fit"
90+
icon={CircusTent}
91+
role="none"
92+
>
93+
<Content>
94+
<p>
95+
Denne komponenten er under aktiv utvikling, og vi trenger din
96+
feedback!
97+
</p>
98+
<p>
99+
Er du eventyrlysten, test den og kom med innspill til oss på{' '}
100+
<a href="https://obos.slack.com/archives/C03FR05FJ9F">Slack</a>.
101+
</p>
77102
</Content>
78103
</Alertbox>
79104
)}

apps/docs/app/routes/_docs/komponenter/index.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { sanityFetch } from '@/lib/sanity';
2-
import { Badge, Card, CardLink, Heading } from '@obosbbl/grunnmuren-react';
2+
import { ComponentStateBadge } from '@/ui/component-state-badge';
3+
import { Card, CardLink, Heading } from '@obosbbl/grunnmuren-react';
34
import { createFileRoute } from '@tanstack/react-router';
45
import { defineQuery } from 'groq';
56

67
const COMPONENTS_INDEX_QUERY = defineQuery(
78
// make sure the slug is always a string so we don't have add fallback value in code just to make TypeScript happy
8-
`*[_type == "component"]{ _id, name, 'slug': coalesce(slug.current, ''), highlightAsNew} | order(name asc)`,
9+
`*[_type == "component"]{ _id, name, 'slug': coalesce(slug.current, ''), componentState} | order(name asc)`,
910
);
1011

1112
export const Route = createFileRoute('/_docs/komponenter/')({
@@ -33,12 +34,10 @@ function Page() {
3334
<CardLink href={`/komponenter/${component.slug}`}>
3435
{component.name}
3536
</CardLink>
36-
{/* TODO: Figure out better way to highlight this */}
37-
{component.highlightAsNew && (
38-
<Badge className="ml-4" color="mint" size="small">
39-
Ny
40-
</Badge>
41-
)}
37+
<ComponentStateBadge
38+
className="ml-4"
39+
componentState={component.componentState}
40+
/>
4241
</Heading>
4342
</Card>
4443
))}

apps/docs/app/routes/_docs/profil/index.tsx

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,5 @@
1-
import { sanityFetch } from '@/lib/sanity';
21
import { Card, CardLink, Heading } from '@obosbbl/grunnmuren-react';
32
import { createFileRoute } from '@tanstack/react-router';
4-
import { defineQuery } from 'groq';
5-
6-
const COMPONENTS_INDEX_QUERY = defineQuery(
7-
// make sure the slug is always a string so we don't have add fallback value in code just to make TypeScript happy
8-
`*[_type == "component"]{ _id, name, 'slug': coalesce(slug.current, '')} | order(name asc)`,
9-
);
103

114
export const Route = createFileRoute('/_docs/profil/')({
125
component: Page,
@@ -16,7 +9,6 @@ export const Route = createFileRoute('/_docs/profil/')({
169
{ name: 'description', content: 'Grunnmuren sin grafiske profil' },
1710
],
1811
}),
19-
loader: () => sanityFetch({ query: COMPONENTS_INDEX_QUERY }),
2012
});
2113

2214
function Page() {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { Badge, type BadgeProps } from '@obosbbl/grunnmuren-react';
2+
3+
type Props = {
4+
componentState?: 'new' | 'deprecated' | 'beta' | 'stable' | null;
5+
className?: string;
6+
};
7+
8+
export function ComponentStateBadge({ componentState, ...props }: Props) {
9+
if (!componentState || componentState === 'stable') {
10+
return null;
11+
}
12+
13+
let color: BadgeProps['color'];
14+
let text: string | undefined;
15+
16+
switch (componentState) {
17+
case 'new':
18+
color = 'mint';
19+
text = 'Ny';
20+
break;
21+
case 'beta':
22+
color = 'blue-dark';
23+
text = 'Beta';
24+
break;
25+
case 'deprecated':
26+
color = 'gray-dark';
27+
text = 'Deprekert';
28+
break;
29+
}
30+
31+
return (
32+
<Badge {...props} size="small" color={color}>
33+
{text}
34+
</Badge>
35+
);
36+
}

apps/docs/app/ui/main-nav.tsx

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,29 @@
11
import { ChevronDown } from '@obosbbl/grunnmuren-icons-react';
2-
import { Badge, Heading } from '@obosbbl/grunnmuren-react';
2+
import { Heading } from '@obosbbl/grunnmuren-react';
33
import { getRouteApi } from '@tanstack/react-router';
44
import { Link } from '@tanstack/react-router';
55
import { Button, Disclosure, DisclosurePanel } from 'react-aria-components';
6+
import { ComponentStateBadge } from './component-state-badge';
67

78
type SubNavItemProps = {
89
to: string;
910
title: string;
10-
highlightAsNew?: boolean | null;
11+
componentState?: 'new' | 'deprecated' | 'beta' | 'stable' | null;
1112
};
1213

13-
const SubNavItem = ({ to, title, highlightAsNew }: SubNavItemProps) => (
14-
<li>
15-
<Link
16-
to={to}
17-
className="description flex items-center justify-between gap-2 rounded-md px-3 py-2 focus-visible:outline-focus focus-visible:outline-focus-inset data-[status=active]:font-bold data-[status=active]:no-underline"
18-
>
19-
{title}
20-
{highlightAsNew && (
21-
<Badge className="no-underline" color="mint" size="small">
22-
Ny
23-
</Badge>
24-
)}
25-
</Link>
26-
</li>
27-
);
14+
const SubNavItem = ({ to, title, componentState }: SubNavItemProps) => {
15+
return (
16+
<li>
17+
<Link
18+
to={to}
19+
className="description flex items-center justify-between gap-2 rounded-md px-3 py-2 focus-visible:outline-focus focus-visible:outline-focus-inset data-[status=active]:font-bold data-[status=active]:no-underline"
20+
>
21+
{title}
22+
<ComponentStateBadge componentState={componentState} />
23+
</Link>
24+
</li>
25+
);
26+
};
2827

2928
type MainNavItemProps = {
3029
title: string;
@@ -77,7 +76,7 @@ export const MainNav = () => {
7776
const componentsNavLinks = data.map((component) => ({
7877
to: `/komponenter/${component.slug}`,
7978
title: component.name as string,
80-
highlightAsNew: component.highlightAsNew,
79+
componentState: component.componentState,
8180
}));
8281

8382
return (

apps/docs/sanity.cli.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { defineCliConfig } from 'sanity/cli';
2+
3+
export default defineCliConfig({
4+
api: {
5+
projectId: 'tq6w17ny',
6+
dataset: 'grunnmuren',
7+
},
8+
});

apps/docs/sanity.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const dataset = 'grunnmuren';
1010

1111
export default defineConfig({
1212
projectId: 'tq6w17ny',
13-
dataset: 'grunnmuren',
13+
dataset,
1414
basePath: '/studio',
1515
title: 'Grunnmuren - Sanity Studio',
1616
auth: obosAuthStore({ dataset }),

0 commit comments

Comments
 (0)