diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 8948f51df5..4a67ddd5a0 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -30,7 +30,7 @@ jobs: env: CI: true - name: Build resources - run: ./node_modules/.bin/gulp gen-icons-json build-translations build-locale-data gather-gallery-demos + run: ./node_modules/.bin/gulp gen-icons-json build-translations build-locale-data gather-gallery-pages - name: Run eslint run: yarn run lint:eslint - name: Run tsc diff --git a/build-scripts/gulp/gallery.js b/build-scripts/gulp/gallery.js index 09ea380d7a..fcca2fc26e 100644 --- a/build-scripts/gulp/gallery.js +++ b/build-scripts/gulp/gallery.js @@ -19,14 +19,14 @@ require("./service-worker.js"); require("./entry-html.js"); require("./rollup.js"); -gulp.task("gather-gallery-demos", async function gatherDemos() { - const demoDir = path.resolve(paths.gallery_dir, "src/demos"); - const files = glob.sync(path.resolve(demoDir, "**/*")); +gulp.task("gather-gallery-pages", async function gatherPages() { + const pageDir = path.resolve(paths.gallery_dir, "src/pages"); + const files = glob.sync(path.resolve(pageDir, "**/*")); const galleryBuild = path.resolve(paths.gallery_dir, "build"); fs.mkdirSync(galleryBuild, { recursive: true }); - let content = "export const DEMOS = {\n"; + let content = "export const PAGES = {\n"; const processed = new Set(); @@ -34,17 +34,17 @@ gulp.task("gather-gallery-demos", async function gatherDemos() { if (fs.lstatSync(file).isDirectory()) { continue; } - demoId = file.substring(demoDir.length + 1, file.lastIndexOf(".")); + const pageId = file.substring(pageDir.length + 1, file.lastIndexOf(".")); - if (processed.has(demoId)) { + if (processed.has(pageId)) { continue; } - processed.add(demoId); + processed.add(pageId); - const [category, name] = demoId.split("/", 2); + const [category, name] = pageId.split("/", 2); - const demoFile = path.resolve(demoDir, `${demoId}.ts`); - const descriptionFile = path.resolve(demoDir, `${demoId}.markdown`); + const demoFile = path.resolve(pageDir, `${pageId}.ts`); + const descriptionFile = path.resolve(pageDir, `${pageId}.markdown`); const hasDemo = fs.existsSync(demoFile); let hasDescription = fs.existsSync(descriptionFile); let metadata = {}; @@ -63,24 +63,25 @@ gulp.task("gather-gallery-demos", async function gatherDemos() { if (descriptionContent === "") { hasDescription = false; } else { + descriptionContent = marked(descriptionContent).replace(/`/g, "\\`"); fs.mkdirSync(path.resolve(galleryBuild, category), { recursive: true }); fs.writeFileSync( - path.resolve(galleryBuild, `${demoId}-description.ts`), + path.resolve(galleryBuild, `${pageId}-description.ts`), ` import {html} from "lit"; - export default html\`${marked(descriptionContent)}\` + export default html\`${descriptionContent}\` ` ); } } - content += ` "${demoId}": { + content += ` "${pageId}": { metadata: ${JSON.stringify(metadata)}, ${ hasDescription - ? `description: () => import("./${demoId}-description").then(m => m.default),` + ? `description: () => import("./${pageId}-description").then(m => m.default),` : "" } - ${hasDemo ? `load: () => import("../src/demos/${demoId}")` : ""} + ${hasDemo ? `demo: () => import("../src/pages/${pageId}")` : ""} },\n`; } @@ -93,51 +94,54 @@ gulp.task("gather-gallery-demos", async function gatherDemos() { delete require.cache[sidebarPath]; const sidebar = require(sidebarPath); - const demosToProcess = {}; + const pagesToProcess = {}; for (const key of processed) { - const [category, demo] = key.split("/", 2); - if (!(category in demosToProcess)) { - demosToProcess[category] = new Set(); + const [category, page] = key.split("/", 2); + if (!(category in pagesToProcess)) { + pagesToProcess[category] = new Set(); } - demosToProcess[category].add(demo); + pagesToProcess[category].add(page); } for (const group of Object.values(sidebar)) { - const toProcess = demosToProcess[group.category]; - delete demosToProcess[group.category]; + const toProcess = pagesToProcess[group.category]; + delete pagesToProcess[group.category]; if (!toProcess) { console.error("Unknown category", group.category); + if (!group.pages) { + group.pages = []; + } continue; } // Any pre-defined groups will not be sorted. - if (group.demos) { - for (const demo of group.demos) { - if (!toProcess.delete(demo)) { - console.error("Found unreferenced demo", demo); + if (group.pages) { + for (const page of group.pages) { + if (!toProcess.delete(page)) { + console.error("Found unreferenced demo", page); } } } else { - group.demos = []; + group.pages = []; } - for (const demo of Array.from(toProcess).sort()) { - group.demos.push(demo); + for (const page of Array.from(toProcess).sort()) { + group.pages.push(page); } } - for (const [category, demos] of Object.entries(demosToProcess)) { + for (const [category, pages] of Object.entries(pagesToProcess)) { sidebar.push({ category, header: category, - demos: Array.from(demos), + pages: Array.from(pages).sort(), }); } content += `export const SIDEBAR = ${JSON.stringify(sidebar, null, 2)};\n`; fs.writeFileSync( - path.resolve(galleryBuild, "import-demos.ts"), + path.resolve(galleryBuild, "import-pages.ts"), content, "utf-8" ); @@ -155,7 +159,7 @@ gulp.task( "gen-icons-json", "build-translations", "build-locale-data", - "gather-gallery-demos" + "gather-gallery-pages" ), "copy-static-gallery", "gen-index-gallery-dev", @@ -166,10 +170,10 @@ gulp.task( async function watchMarkdownFiles() { gulp.watch( [ - path.resolve(paths.gallery_dir, "src/demos/**/*.markdown"), + path.resolve(paths.gallery_dir, "src/pages/**/*.markdown"), path.resolve(paths.gallery_dir, "sidebar.js"), ], - gulp.series("gather-gallery-demos") + gulp.series("gather-gallery-pages") ); } ) @@ -188,7 +192,7 @@ gulp.task( "gen-icons-json", "build-translations", "build-locale-data", - "gather-gallery-demos" + "gather-gallery-pages" ), "copy-static-gallery", env.useRollup() ? "rollup-prod-gallery" : "webpack-prod-gallery", diff --git a/gallery/script/netlify_build_gallery b/gallery/script/netlify_build_gallery index 173b77d73f..295486a2b1 100755 --- a/gallery/script/netlify_build_gallery +++ b/gallery/script/netlify_build_gallery @@ -1,6 +1,6 @@ #!/bin/bash -TARGET_LABEL="Needs gallery preview" +TARGET_LABEL="Needs design preview" if [[ "$NETLIFY" != "true" ]]; then echo "This script can only be run on Netlify" @@ -13,7 +13,7 @@ function createStatus() { target_url="$3" curl -X POST -H "Accept: application/vnd.github.v3+json" -H "Authorization: token $GITHUB_TOKEN" \ "https://api.github.com/repos/home-assistant/frontend/statuses/$COMMIT_REF" \ - -d '{"state": "'"${state}"'", "context": "Netlify/Gallery Preview Build", "description": "'"$description"'", "target_url": "'"$target_url"'"}' + -d '{"state": "'"${state}"'", "context": "Netlify/Design Preview Build", "description": "'"$description"'", "target_url": "'"$target_url"'"}' } @@ -22,7 +22,7 @@ if [[ "${PULL_REQUEST}" == "false" ]]; then else if [[ "$(curl -sSLf -H "Accept: application/vnd.github.v3+json" -H "Authorization: token $GITHUB_TOKEN" \ "https://api.github.com/repos/home-assistant/frontend/pulls/${REVIEW_ID}" | jq '.labels[].name' -r)" =~ "$TARGET_LABEL" ]]; then - createStatus "pending" "Building gallery preview" "https://app.netlify.com/sites/home-assistant-gallery/deploys/$BUILD_ID" + createStatus "pending" "Building design preview" "https://app.netlify.com/sites/home-assistant-gallery/deploys/$BUILD_ID" gulp build-gallery if [ $? -eq 0 ]; then createStatus "success" "Build complete" "$DEPLOY_URL" diff --git a/gallery/sidebar.js b/gallery/sidebar.js index 2d40478a88..978948eb85 100644 --- a/gallery/sidebar.js +++ b/gallery/sidebar.js @@ -1,16 +1,17 @@ module.exports = [ { - category: "introduction", - demos: ["introduction"], + // This section has no header and so all page links are shown directly in the sidebar + category: "concepts", + pages: ["home"], }, { category: "lovelace", - // Each section has a header + // Label for in the sidebar header: "Lovelace", - // Specify demos to make sure they are put on top. - demos: [], - // Add a demoStart to automatically gather demos based on their name + // Specify order of pages. Any pages in the category folder but not listed here will + // automatically be added after the pages listed here. + pages: ["introduction"], }, { category: "automation", @@ -19,22 +20,17 @@ module.exports = [ { category: "components", header: "Components", - demos: [ - "ha-alert", - "ha-bar", - "ha-chips", - "ha-faded", - "ha-form", - "ha-label-badge", - "ha-selector", - ], }, { category: "more-info", - header: "More Info", + header: "More Info dialogs", }, { - category: "rest", - header: "Rest", + category: "misc", + header: "Miscelaneous", + }, + { + category: "design.home-assistant.io", + header: "Design Documentation", }, ]; diff --git a/gallery/src/components/demo-description.ts b/gallery/src/components/demo-description.ts deleted file mode 100644 index 41dc6fc4a0..0000000000 --- a/gallery/src/components/demo-description.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { html, css, LitElement } from "lit"; -import { customElement, property } from "lit/decorators"; -import { until } from "lit/directives/until"; -import { haStyle } from "../../../src/resources/styles"; -import { DEMOS } from "../../build/import-demos"; - -@customElement("demo-description") -class DemoDescription extends LitElement { - @property() public demo!: string; - - render() { - if (!DEMOS[this.demo].description) { - return ""; - } - return html` - ${until( - DEMOS[this.demo].description().then( - (content) => html` - -
${content}
-
- ` - ), - "" - )} - `; - } - - static styles = [ - haStyle, - css` - ha-card { - max-width: 600px; - margin: 16px auto; - } - `, - ]; -} - -declare global { - interface HTMLElementTagNameMap { - "demo-description": DemoDescription; - } -} diff --git a/gallery/src/components/page-description.ts b/gallery/src/components/page-description.ts new file mode 100644 index 0000000000..abcdcc5820 --- /dev/null +++ b/gallery/src/components/page-description.ts @@ -0,0 +1,50 @@ +import { html, css } from "lit"; +import { customElement, property } from "lit/decorators"; +import { until } from "lit/directives/until"; +import { HaMarkdown } from "../../../src/components/ha-markdown"; +import { PAGES } from "../../build/import-pages"; + +@customElement("page-description") +class PageDescription extends HaMarkdown { + @property() public page!: string; + + render() { + if (!PAGES[this.page].description) { + return html``; + } + return html` + ${until( + PAGES[this.page].description().then( + (content) => html` + +
${content}
+
+ ` + ), + "" + )} + `; + } + + static styles = [ + HaMarkdown.styles, + css` + ha-card { + max-width: 600px; + margin: 16px auto; + } + .card-content > *:first-child { + margin-top: 0; + } + .card-content > *:last-child { + margin-bottom: 0; + } + `, + ]; +} + +declare global { + interface HTMLElementTagNameMap { + "page-description": PageDescription; + } +} diff --git a/gallery/src/ha-gallery.ts b/gallery/src/ha-gallery.ts index 0454111a16..553ba4479f 100644 --- a/gallery/src/ha-gallery.ts +++ b/gallery/src/ha-gallery.ts @@ -7,12 +7,12 @@ import "../../src/components/ha-card"; import "../../src/components/ha-icon-button"; import "../../src/managers/notification-manager"; import { haStyle } from "../../src/resources/styles"; -import { DEMOS, SIDEBAR } from "../build/import-demos"; +import { PAGES, SIDEBAR } from "../build/import-pages"; import { dynamicElement } from "../../src/common/dom/dynamic-element-directive"; -import "./components/demo-description"; +import "./components/page-description"; const GITHUB_DEMO_URL = - "https://github.com/home-assistant/frontend/blob/dev/gallery/src/demos/"; + "https://github.com/home-assistant/frontend/blob/dev/gallery/src/pages/"; const FAKE_HASS = { // Just enough for computeRTL for notification-manager @@ -24,9 +24,9 @@ const FAKE_HASS = { @customElement("ha-gallery") class HaGallery extends LitElement { - @property() private _demo = + @property() private _page = document.location.hash.substring(1) || - `${SIDEBAR[0].category}/${SIDEBAR[0].demos![0]}`; + `${SIDEBAR[0].category}/${SIDEBAR[0].pages![0]}`; @query("notification-manager") private _notifications!: HTMLElementTagNameMap["notification-manager"]; @@ -42,12 +42,12 @@ class HaGallery extends LitElement { for (const group of SIDEBAR) { const links: unknown[] = []; - for (const demo of group.demos!) { - const key = `${group.category}/${demo}`; - const active = this._demo === key; - const title = DEMOS[key].metadata.title || demo; + for (const page of group.pages!) { + const key = `${group.category}/${page}`; + const active = this._page === key; + const title = PAGES[key].metadata.title || page; links.push(html` - ${title} + ${title} `); } @@ -81,28 +81,28 @@ class HaGallery extends LitElement { >
- ${DEMOS[this._demo].metadata.title || this._demo.split("/")[1]} + ${PAGES[this._page].metadata.title || this._page.split("/")[1]}
- - ${dynamicElement(`demo-${this._demo.replace("/", "-")}`)} -