Skip to content

Commit aa11b00

Browse files
SnugugSam Richard
andauthored
🆕 Add Tutorial content type and CMS content preview (#768)
* Add DB migration script * Add development dataset switch Lets site run off of development database instead of production, allowing for pre-production testing of CMS-tied changes * Add I/O 2024 theme There's a lot going on here so we can reuse official assets; I don't know if I like it or not, but we'll see how it goes * Improve borders, especially on the home page * Add archive build and serve options * Remove unused codepaths from Sanity * WIP Tutorial content type * Updated Tutorial schema * Add tutorial microcopy * Simplify tutorial content type * Add back and forward direction to generic CTAs * Add Software component * Update CTA styling if icons are present * Tutorial query and types * Adapt doc layout to include generic content area, not just type content area * Add tutorial templates * Clean up logging * Fix CLI build * Fix Code filename If it's shell with no filename, don't include label. Fix spacing * Make cursor pointer for reinforcement * Fix canvas taking over page on load by only triggering if visible * Only include file download/link if on intro * Fix prerequisite rendering * Remove unneeded log * Remove broken ESLint rule * Make some Sanity queries reusable, for previews * Add views path to TSConfig * Add dark mode outline * Export TOC title * Fix dark mode color * Migrate preview-able content to Views * Add Preview route * Update Preview view to support final implementation * Include sanity API info for preview * Update for sharing overrides * Add preview generation log * Remove recommended Think this may be breaking preview URL * Add Preview Key to env vars * Fix linting * Move slugify to proper dependency * More dependnecies moving up * Swap Prism for Shiki Prism has given us so many problems in this codebase, and is now blocking Preview because of its weird global handling. Swapping to Shiki. Eventually should add our own theme * Update PNPM lock * Swap preview URL depending on mode, for working against localhost * Remove env logging --------- Co-authored-by: Sam Richard <samrichard@google.com>
1 parent fc05fbc commit aa11b00

51 files changed

Lines changed: 3289 additions & 3563 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/tbd-cms.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,4 @@ jobs:
7878
SANITY_AUTH_TOKEN: ${{ secrets.SANITY_DEPLOY_TOKEN }}
7979
SANITY_STUDIO_PROJECT: ${{ secrets.SANITY_PROJECT_ID }}
8080
SANITY_STUDIO_PROD_DATASET: ${{ secrets.SANITY_DATASET }}
81+
SANITY_STUDIO_PREVIEW_KEY: ${{ secrets.PREVIEW_KEY }}

.github/workflows/tbd-site.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ jobs:
101101
with:
102102
envkey_SANITY_WEBHOOK_SECRET: ${{ secrets.SANITY_WEBHOOK_SECRET }}
103103
envkey_GITHUB_TOKEN: ${{ secrets.WORKFLOW_PAT }}
104+
envkey_SANITY_PROJECT_ID: ${{ secrets.SANITY_PROJECT_ID }}
105+
envkey_SANITY_DATASET: ${{ secrets.SANITY_DATASET }}
106+
envkey_SANITY_TOKEN: ${{ secrets.SANITY_TOKEN }}
107+
envkey_PREVIEW_KEY: ${{ secrets.PREVIEW_KEY }}
104108
directory: site
105109
- name: Deploy Hosting
106110
uses: FirebaseExtended/action-hosting-deploy@v0

cms/lib/desk.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { RiTodoLine } from 'react-icons/ri';
2727
import { MdOutlineNewReleases } from 'react-icons/md';
2828

2929
import { AiOutlineFileSearch } from 'react-icons/ai';
30-
import { IoLogoPwa } from 'react-icons/io5';
30+
import { IoLogoPwa, IoSchoolOutline } from 'react-icons/io5';
3131
import { LuPaintbrush2, LuScissors } from 'react-icons/lu';
3232
// import { TfiAnnouncement } from 'react-icons/tfi';
3333
import { SINGLETONS, LANGUAGES } from './constants';
@@ -113,6 +113,15 @@ export const deskStructure = (
113113
`_type == 'documentation' && (language == 'en' || !defined(language) || language == 'en')`,
114114
),
115115
),
116+
// All base-language tutorial
117+
S.listItem()
118+
.title('Tutorials')
119+
.icon(IoSchoolOutline)
120+
.child(
121+
S.documentTypeList('tutorial').filter(
122+
`_type == 'tutorial' && (language == 'en' || !defined(language) || language == 'en')`,
123+
),
124+
),
116125
// All base-language release notes
117126
S.listItem()
118127
.title('Release Notes')

cms/lib/desk/Preview.tsx

Lines changed: 94 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,110 @@
1-
import { ComponentView } from 'sanity/desk';
1+
import { DeskToolContextValue } from 'sanity/desk';
2+
import { FaRegCopy } from 'react-icons/fa';
3+
import { IoReload } from 'react-icons/io5';
4+
import { RxOpenInNewWindow } from 'react-icons/rx';
25

36
/**
47
*
58
* @param {Object} context
69
* @return {ComponentView}
710
*/
8-
export const Preview = (context: ComponentView) => {
9-
const { document, documentId, schemaType } = context;
11+
export const Preview = (context: DeskToolContextValue) => {
12+
const { document: d, schemaType } = context;
13+
const types = [
14+
'documentation',
15+
'post',
16+
'story',
17+
'tutorial',
18+
// 'landing',
19+
// 'release',
20+
];
21+
22+
if (!types.includes(schemaType.name)) {
23+
return <h1>Preview not supported for this content type</h1>;
24+
}
25+
26+
const base =
27+
process.env.MODE === 'development'
28+
? 'http://localhost:4321'
29+
: 'https://chromeos.dev';
1030
// Site preview URL?
11-
const previewURL = `https://staging.chromeos.dev/en/posts/${document.displayed.slug.current}?id=${document.displayed._id}&rev=${document.displayed._rev}&preview=true`;
12-
console.log(document);
13-
console.log(documentId);
14-
console.log(schemaType);
15-
console.log(previewURL);
31+
const previewURL = `${base}/preview?id=${d.displayed._id}&rev=${
32+
d.displayed._rev
33+
}&key=${encodeURIComponent(process.env.SANITY_STUDIO_PREVIEW_KEY)}`;
1634

17-
const style = {
18-
width: '100%',
19-
height: '50vh',
20-
};
35+
const id = `preview-${Math.round(Math.random() * 1000)}`;
2136

2237
return (
2338
<div>
24-
<h1>Document Preview</h1>
25-
<p>Preview URL: {previewURL}</p>
39+
<h1>Preview</h1>
40+
<div
41+
className="actions"
42+
style={{
43+
display: 'flex',
44+
justifyContent: 'space-between',
45+
paddingInline: '1rem',
46+
paddingBlock: '.5rem',
47+
backgroundColor: '#111',
48+
gap: '1rem',
49+
}}
50+
>
51+
<button
52+
style={{
53+
appearance: 'none',
54+
border: 'none',
55+
backgroundColor: '#111',
56+
display: 'flex',
57+
alignItems: 'center',
58+
gap: '.5rem',
59+
cursor: 'pointer',
60+
}}
61+
onClick={async () => {
62+
await navigator.clipboard.writeText(previewURL);
63+
}}
64+
>
65+
<FaRegCopy></FaRegCopy> Copy URL
66+
</button>
67+
<span
68+
style={{
69+
display: 'flex',
70+
justifyContent: 'space-between',
71+
gap: '1rem',
72+
}}
73+
>
74+
<button
75+
style={{
76+
appearance: 'none',
77+
border: 'none',
78+
backgroundColor: '#111',
79+
cursor: 'pointer',
80+
}}
81+
onClick={() => {
82+
const iframe = document.querySelector(`#${id}`);
83+
if (iframe) iframe.src = previewURL;
84+
}}
85+
>
86+
<IoReload></IoReload>
87+
</button>
88+
<a
89+
href={previewURL}
90+
target="_blank"
91+
rel="noopener noreferrer"
92+
style={{
93+
color: 'white',
94+
}}
95+
>
96+
<RxOpenInNewWindow />
97+
</a>
98+
</span>
99+
</div>
26100
<iframe
27101
title="preview"
28-
src="https://chromeos.dev"
29-
frameBorder="0"
30-
style={style}
102+
src={previewURL}
103+
style={{
104+
width: '100%',
105+
height: '50vh',
106+
}}
107+
id={id}
31108
></iframe>
32109
</div>
33110
);

cms/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"private": true,
44
"version": "1.0.0",
55
"main": "package.json",
6-
"license": "UNLICENSED",
6+
"license": "Apache-2.0",
77
"scripts": {
88
"dev": "sanity dev",
99
"start": "sanity start",
@@ -22,7 +22,8 @@
2222
"prettier:fix": "prettier --write .",
2323
"sanity": "sanity",
2424
"sanity:create:singletons": "sanity exec scripts/createSingletons.ts --with-user-token",
25-
"sanity:test:singletons": "TARGET=dev sanity exec scripts/createSingletons.ts --with-user-token"
25+
"sanity:test:singletons": "TARGET=dev sanity exec scripts/createSingletons.ts --with-user-token",
26+
"sanity:pull": "sanity dataset export production && sanity dataset import --replace production.tar.gz development && rm production.tar.gz"
2627
},
2728
"keywords": [
2829
"sanity"

cms/schemas/announcement.ts

Lines changed: 2 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
import { defineField, defineType, defineArrayMember } from 'sanity';
16+
import { defineField, defineType } from 'sanity';
1717
import { preview } from '$lib/previews/localization';
1818

1919
export default defineType({
@@ -29,43 +29,7 @@ export default defineType({
2929
defineField({
3030
name: 'body',
3131
title: 'Announcement',
32-
type: 'array',
33-
of: [
34-
defineArrayMember({
35-
title: 'Block',
36-
type: 'block',
37-
// Styles let you set what your user can mark up blocks with. These
38-
// correspond with HTML tags, but you can set any title or value
39-
// you want and decide how you want to deal with it where you want to
40-
// use your content.
41-
styles: [{ title: 'Normal', value: 'normal' }],
42-
lists: [],
43-
// Marks let you mark up inline text in the block editor.
44-
marks: {
45-
// Decorators usually describe a single property – e.g. a typographic
46-
// preference or highlighting by editors.
47-
decorators: [
48-
{ title: 'Strong', value: 'strong' },
49-
{ title: 'Emphasis', value: 'em' },
50-
],
51-
// Annotations can be any object structure – e.g. a link or a footnote.
52-
annotations: [
53-
{
54-
title: 'Link',
55-
name: 'link',
56-
type: 'object',
57-
fields: [
58-
defineField({
59-
title: 'Source',
60-
name: 'source',
61-
type: 'link',
62-
}),
63-
],
64-
},
65-
],
66-
},
67-
}),
68-
],
32+
type: 'restricted-inline-block',
6933
validation: (Rule) => Rule.required(),
7034
}),
7135
],
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/**
2+
* Copyright 2022 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
import { defineType, defineArrayMember, defineField } from 'sanity';
17+
import { KBDDecorator } from '$components/KBD';
18+
19+
/**
20+
* This is the schema definition for the rich text fields used for
21+
* for this blog studio. When you import it in schemas.js it can be
22+
* reused in other parts of the studio with:
23+
* {
24+
* name: 'someName',
25+
* title: 'Some title',
26+
* type: 'blockContent'
27+
* }
28+
*/
29+
export default defineType({
30+
title: 'Restricted Inline Block Content',
31+
name: 'restricted-inline-block',
32+
type: 'array',
33+
of: [
34+
defineArrayMember({
35+
title: 'Block',
36+
type: 'block',
37+
// Styles let you set what your user can mark up blocks with. These
38+
// correspond with HTML tags, but you can set any title or value
39+
// you want and decide how you want to deal with it where you want to
40+
// use your content.
41+
styles: [{ title: 'Normal', value: 'normal' }],
42+
lists: [],
43+
// Marks let you mark up inline text in the block editor.
44+
marks: {
45+
// Decorators usually describe a single property – e.g. a typographic
46+
// preference or highlighting by editors.
47+
decorators: [
48+
{ title: 'Strong', value: 'strong' },
49+
{ title: 'Emphasis', value: 'em' },
50+
KBDDecorator,
51+
{ title: 'Code', value: 'code' },
52+
],
53+
// Annotations can be any object structure – e.g. a link or a footnote.
54+
annotations: [
55+
{
56+
title: 'Link',
57+
name: 'link',
58+
type: 'object',
59+
fields: [
60+
defineField({
61+
title: 'Source',
62+
name: 'source',
63+
type: 'link',
64+
}),
65+
],
66+
},
67+
{
68+
title: 'Abbreviation',
69+
name: 'abbreviation',
70+
type: 'object',
71+
fields: [
72+
defineField({
73+
name: 'abbreviation',
74+
type: 'abbreviation',
75+
}),
76+
],
77+
},
78+
],
79+
},
80+
}),
81+
],
82+
});

cms/schemas/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import fullBlockField from '$fields/full-block';
1818
import restrictedBlockField from '$fields/restricted-block';
1919
import inlineBlockField from '$fields/inline-block';
20+
import restrictedInlineBlockField from '$fields/restricted-inline-block';
2021
import cellBlockField from '$fields/cell-block';
2122
import pictureField from '$fields/picture';
2223
import titleField from '$fields/title';
@@ -79,6 +80,7 @@ import releases from './releases';
7980
import release from './release';
8081
import snippet from './snippet';
8182
import announcement from './announcement';
83+
import tutorial from './tutorial';
8284

8385
export const schemaTypes = [
8486
// Schemas
@@ -103,11 +105,13 @@ export const schemaTypes = [
103105
release,
104106
snippet,
105107
announcement,
108+
tutorial,
106109

107110
// Fields
108111
fullBlockField,
109112
restrictedBlockField,
110113
inlineBlockField,
114+
restrictedInlineBlockField,
111115
cellBlockField,
112116
pictureField,
113117
titleField,

0 commit comments

Comments
 (0)