From a3d9adffdc155d4b6311aad28c36210c7023d7e8 Mon Sep 17 00:00:00 2001 From: Matt Hillsdon Date: Wed, 18 Oct 2023 11:19:33 +0100 Subject: [PATCH] Add a limited drafts flag Good enough to view new Reference sections assuming they're published but the top-level document that adds them is a draft. --- src/documentation/reference/content.ts | 21 ++++++++++++++----- src/documentation/reference/model.ts | 7 +++++++ src/documentation/search/search.test.ts | 4 ++++ src/flags.ts | 27 +++++++++++++++---------- 4 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/documentation/reference/content.ts b/src/documentation/reference/content.ts index 9d1e7a629..d8bd8c52e 100644 --- a/src/documentation/reference/content.ts +++ b/src/documentation/reference/content.ts @@ -4,6 +4,7 @@ * SPDX-License-Identifier: MIT */ import { fetchContent } from "../../common/sanity"; +import { flags } from "../../flags"; import { Toolkit, ToolkitTopic, ToolkitTopicEntry } from "./model"; export const fetchReferenceToolkit = async ( @@ -29,12 +30,16 @@ export const getTopicAndEntry = ( return [entry.parent, entry]; }; -// For now we just slurp the whole toolkit at once. -// Might revisit depending on eventual size. +// We just slurp the whole toolkit at once. +// This is necessary for the client-side search index. const toolkitQuery = (languageId: string): string => { + // The flag applies to the top-level document so for now there's no support for viewing drafts further down. + const noDraftsConstraint = flags.drafts + ? "" + : `&& (_id in path("drafts.**"))`; return ` - *[_type == "toolkit" && language == "${languageId}" && (slug.current == "explore" || slug.current == "reference") && !(_id in path("drafts.**"))]{ - id, name, description, language, + *[_type == "toolkit" && language == "${languageId}" && (slug.current == "explore" || slug.current == "reference") ${noDraftsConstraint}]{ + _id, id, name, description, language, contents[]->{ name, slug, compatibility, subtitle, image, introduction[] { @@ -75,11 +80,17 @@ const toolkitQuery = (languageId: string): string => { }`; }; +const isDraft = (document: { _id: string }) => /^drafts\./.test(document._id); + const adaptContent = (result: any): Toolkit | undefined => { - const toolkits = result as Toolkit[]; + let toolkits = result as Toolkit[]; if (toolkits.length === 0) { return undefined; } + // Prefer drafts if we got both + if (toolkits.some(isDraft)) { + toolkits = toolkits.filter(isDraft); + } if (toolkits.length > 1) { throw new Error("Unexpected results"); } diff --git a/src/documentation/reference/model.ts b/src/documentation/reference/model.ts index c31f2a1fe..5992c6fab 100644 --- a/src/documentation/reference/model.ts +++ b/src/documentation/reference/model.ts @@ -8,6 +8,13 @@ import { PortableText, SimpleImage, Slug } from "../../common/sanity"; import { HasCompatibility } from "../common/model"; export interface Toolkit { + /** + * The CMS internal id. + */ + _id: string; + /** + * The logical id. + */ id: string; name: string; description: string; diff --git a/src/documentation/search/search.test.ts b/src/documentation/search/search.test.ts index 3d8630c21..2c2f838f5 100644 --- a/src/documentation/search/search.test.ts +++ b/src/documentation/search/search.test.ts @@ -101,6 +101,7 @@ describe("buildReferenceIndex", () => { it("uses language from the toolkit for the Reference index", async () => { const api: ApiDocsResponse = {}; const referenceEn: Toolkit = { + _id: "asdf", id: "reference", description: "description", language: "en", @@ -154,6 +155,7 @@ describe("SearchWorker", () => { const indexMessage: IndexMessage = { kind: "index", reference: { + _id: "asdf", id: "reference", description: "Reference stuff", name: "Reference", @@ -185,6 +187,7 @@ describe("SearchWorker", () => { const emptyIndex: IndexMessage = { kind: "index", reference: { + _id: "asdf", id: "reference", description: "Reference stuff", name: "Reference", @@ -196,6 +199,7 @@ describe("SearchWorker", () => { const fullIndex: IndexMessage = { kind: "index", reference: { + _id: "asdf", id: "reference", description: "Reference stuff", name: "Reference", diff --git a/src/flags.ts b/src/flags.ts index 272a115f6..0e0bc17a4 100644 --- a/src/flags.ts +++ b/src/flags.ts @@ -16,30 +16,34 @@ import { Stage, stage as stageFromEnvironment } from "./environment"; * A union of the flag names (alphabetical order). */ export type Flag = - /** - * Enables verbose debug logging to the console of drag events. - */ - | "dndDebug" - /** * Flag to add a beta notice. Enabled for staging site but not production stages. */ | "betaNotice" - /** - * Disables the pop-up welcome dialog. + * Enables verbose debug logging to the console of drag events. + */ + | "dndDebug" + /** + * Shows CMS drafts in preference to live content. * - * Added to support user-testing and has the nice side-effect of disabling - * the dialog for local development so is worth keeping for that use alone. + * Currently only supported for the reference content. */ - | "noWelcome" + | "drafts" /** * Disables language selection from the settings menu. * * Added so we can embed the editor in micro:bit classroom without competing language * options. The language selected in classroom is passed through via query param. */ - | "noLang"; + | "noLang" + /** + * Disables the pop-up welcome dialog. + * + * Added to support user-testing and has the nice side-effect of disabling + * the dialog for local development so is worth keeping for that use alone. + */ + | "noWelcome"; interface FlagMetadata { defaultOnStages: Stage[]; @@ -49,6 +53,7 @@ interface FlagMetadata { const allFlags: FlagMetadata[] = [ // Alphabetical order. { name: "dndDebug", defaultOnStages: [] }, + { name: "drafts", defaultOnStages: ["local", "REVIEW"] }, { name: "betaNotice", defaultOnStages: ["local", "REVIEW", "STAGING"] }, { name: "noWelcome", defaultOnStages: ["local", "REVIEW"] }, { name: "noLang", defaultOnStages: [] },