From 1d5e34f1a6991a7a6ccadd3b8c48548f7005bca0 Mon Sep 17 00:00:00 2001 From: DrMint <29893320+DrMint@users.noreply.github.com> Date: Fri, 22 Mar 2024 23:14:47 +0100 Subject: [PATCH] improve sources and parent pages --- TODO.md | 1 + src/components/AppLayout/AppEmptyLayout.astro | 4 +- .../AppLayout/components/Topbar/Topbar.astro | 4 +- .../Topbar/components/ParentPagesButton.astro | 25 ++++--- .../Topbar/components/ReturnToButton.astro | 38 ++++------ .../ParentPageLink.astro => SourceRow.astro} | 36 ++++------ src/i18n/i18n.ts | 69 ++++++++++++++++++- src/i18n/wordings-keys.ts | 9 ++- .../_components/TimelineSourcesButton.astro | 24 +------ src/shared/payload/payload-sdk.ts | 20 ++---- 10 files changed, 131 insertions(+), 99 deletions(-) rename src/components/{AppLayout/components/Topbar/components/ParentPageLink.astro => SourceRow.astro} (52%) diff --git a/TODO.md b/TODO.md index 1c8e386..1d094f7 100644 --- a/TODO.md +++ b/TODO.md @@ -8,6 +8,7 @@ ## Mid term - Support for nameless section +- [Timeline] Error if collectible not published? - [Collectibles] Create page for gallery - [Collectibles] Create page for scans - When the tags overflow, the tag group name should be align start (see http://localhost:12499/en/pages/magnitude-negative-chapter-1) diff --git a/src/components/AppLayout/AppEmptyLayout.astro b/src/components/AppLayout/AppEmptyLayout.astro index 83378a9..03d05cb 100644 --- a/src/components/AppLayout/AppEmptyLayout.astro +++ b/src/components/AppLayout/AppEmptyLayout.astro @@ -2,13 +2,13 @@ import Html from "./components/Html.astro"; import Topbar from "./components/Topbar/Topbar.astro"; import Footer from "./components/Footer.astro"; -import type { ParentPage, PayloadImage } from "src/shared/payload/payload-sdk"; +import type { EndpointSource, PayloadImage } from "src/shared/payload/payload-sdk"; import AppLayoutBackgroundImg from "./components/AppLayoutBackgroundImg.astro"; import type { ComponentProps } from "astro/types"; interface Props { openGraph?: ComponentProps["openGraph"]; - parentPages?: ParentPage[]; + parentPages?: EndpointSource[]; hideFooterLinks?: boolean; backgroundImage?: PayloadImage | undefined; } diff --git a/src/components/AppLayout/components/Topbar/Topbar.astro b/src/components/AppLayout/components/Topbar/Topbar.astro index aec14e5..0e5d288 100644 --- a/src/components/AppLayout/components/Topbar/Topbar.astro +++ b/src/components/AppLayout/components/Topbar/Topbar.astro @@ -4,12 +4,12 @@ import Button from "components/Button.astro"; import ThemeSelector from "./components/ThemeSelector.astro"; import LanguageSelector from "./components/LanguageSelector.astro"; import CurrencySelector from "./components/CurrencySelector.astro"; -import type { ParentPage } from "src/shared/payload/payload-sdk"; import ParentPagesButton from "./components/ParentPagesButton.astro"; import { getI18n } from "src/i18n/i18n"; +import type { EndpointSource } from "src/shared/payload/payload-sdk"; interface Props { - parentPages?: ParentPage[] | undefined; + parentPages?: EndpointSource[] | undefined; hideHomeButton?: boolean; } diff --git a/src/components/AppLayout/components/Topbar/components/ParentPagesButton.astro b/src/components/AppLayout/components/Topbar/components/ParentPagesButton.astro index 087aa9f..0a8cda5 100644 --- a/src/components/AppLayout/components/Topbar/components/ParentPagesButton.astro +++ b/src/components/AppLayout/components/Topbar/components/ParentPagesButton.astro @@ -1,13 +1,13 @@ --- import Tooltip from "components/Tooltip.astro"; -import type { ParentPage } from "src/shared/payload/payload-sdk"; -import ParentPageLink from "./ParentPageLink.astro"; import { Icon } from "astro-icon/components"; import { getI18n } from "src/i18n/i18n"; import ReturnToButton from "./ReturnToButton.astro"; +import type { EndpointSource } from "src/shared/payload/payload-sdk"; +import SourceRow from "components/SourceRow.astro"; interface Props { - parentPages: ParentPage[]; + parentPages: EndpointSource[]; } const { parentPages } = Astro.props; @@ -24,9 +24,11 @@ const { t } = await getI18n(Astro.locals.currentLocale);

{t("header.nav.parentPages.tooltip")}

- {parentPages.map((parentPage) => ( - - ))} +
+ {parentPages.map((parentPage) => ( + + ))} +
@@ -44,7 +46,14 @@ const { t } = await getI18n(Astro.locals.currentLocale); diff --git a/src/components/AppLayout/components/Topbar/components/ReturnToButton.astro b/src/components/AppLayout/components/Topbar/components/ReturnToButton.astro index 44eb9e1..92a4cb2 100644 --- a/src/components/AppLayout/components/Topbar/components/ReturnToButton.astro +++ b/src/components/AppLayout/components/Topbar/components/ReturnToButton.astro @@ -1,44 +1,32 @@ --- import { Icon } from "astro-icon/components"; import { getI18n } from "src/i18n/i18n"; -import { Collections, type ParentPage } from "src/shared/payload/payload-sdk"; +import type { EndpointSource } from "src/shared/payload/payload-sdk"; interface Props { - parentPage: ParentPage; + parentPage: EndpointSource; } const { parentPage } = Astro.props; -const { getLocalizedMatch, getLocalizedUrl, t } = await getI18n(Astro.locals.currentLocale); +const { formatEndpointSource } = await getI18n(Astro.locals.currentLocale); -const translation = getLocalizedMatch(parentPage.translations); - -let href = ""; -let collectionLabel = ""; -switch (parentPage.collection) { - case Collections.Folders: - href = getLocalizedUrl(`/folders/${parentPage.slug}`); - collectionLabel = t("header.nav.parentPages.collections.folder"); - break; - - case Collections.Collectibles: - href = getLocalizedUrl(`/collectibles/${parentPage.slug}`); - collectionLabel = t("header.nav.parentPages.collections.collectible"); - break; - - default: - href = "/404"; - break; -} +const { + href, + typeLabel, + label, + target = undefined, + rel = undefined, +} = formatEndpointSource(parentPage); --- {/* ------------------------------------------- HTML ------------------------------------------- */} - +

- {collectionLabel} - {translation.name} + {typeLabel} + {label}

diff --git a/src/components/AppLayout/components/Topbar/components/ParentPageLink.astro b/src/components/SourceRow.astro similarity index 52% rename from src/components/AppLayout/components/Topbar/components/ParentPageLink.astro rename to src/components/SourceRow.astro index aa0f924..cb4ef1d 100644 --- a/src/components/AppLayout/components/Topbar/components/ParentPageLink.astro +++ b/src/components/SourceRow.astro @@ -1,38 +1,26 @@ --- import { getI18n } from "src/i18n/i18n"; -import { Collections, type ParentPage } from "src/shared/payload/payload-sdk"; +import type { EndpointSource } from "src/shared/payload/payload-sdk"; interface Props { - parentPage: ParentPage; + source: EndpointSource; } -const { parentPage } = Astro.props; -const { getLocalizedMatch, getLocalizedUrl, t } = await getI18n(Astro.locals.currentLocale); +const { source } = Astro.props; +const { formatEndpointSource } = await getI18n(Astro.locals.currentLocale); -const translation = getLocalizedMatch(parentPage.translations); - -let href = ""; -let collectionLabel = ""; -switch (parentPage.collection) { - case Collections.Folders: - href = getLocalizedUrl(`/folders/${parentPage.slug}`); - collectionLabel = t("header.nav.parentPages.collections.folder"); - break; - - case Collections.Collectibles: - href = getLocalizedUrl(`/collectibles/${parentPage.slug}`); - collectionLabel = t("header.nav.parentPages.collections.collectible"); - break; - - default: - href = "/404"; - break; -} +const { + href, + typeLabel, + label, + target = undefined, + rel = undefined, +} = formatEndpointSource(source); --- {/* ------------------------------------------- HTML ------------------------------------------- */} -
{collectionLabel}

{translation.name}

+
{typeLabel}

{label}

{/* ------------------------------------------- CSS -------------------------------------------- */} diff --git a/src/i18n/i18n.ts b/src/i18n/i18n.ts index 739c50e..812f5b7 100644 --- a/src/i18n/i18n.ts +++ b/src/i18n/i18n.ts @@ -1,7 +1,7 @@ import type { WordingKey } from "src/i18n/wordings-keys"; -import type { ChronologyEvent } from "src/shared/payload/payload-sdk"; +import type { ChronologyEvent, EndpointSource } from "src/shared/payload/payload-sdk"; import { cache } from "src/utils/cachedPayload"; -import { capitalize } from "src/utils/format"; +import { capitalize, formatInlineTitle } from "src/utils/format"; export const defaultLocale = "en"; @@ -173,6 +173,70 @@ export const getI18n = async (locale: string) => { ); }; + const formatEndpointSource = (source: EndpointSource) => { + switch (source.type) { + case "url": + return { + href: source.url, + typeLabel: t("global.sources.typeLabel.url"), + label: source.label, + target: "_blank", + rel: "noopener noreferrer", + }; + + case "collectible": + const rangeLabel = (() => { + switch (source.range?.type) { + case "timestamp": + return t("global.sources.typeLabel.collectible.range.timestamp", { + page: source.range.timestamp, + }); + + case "page": + return t("global.sources.typeLabel.collectible.range.page", { + page: source.range.page, + }); + + case "custom": + return t("global.sources.typeLabel.collectible.range.custom", { + note: getLocalizedMatch(source.range.translations).note, + }); + + case undefined: + default: + return ""; + } + })(); + + return { + href: getLocalizedUrl(`/collectibles/${source.collectible.slug}`), + typeLabel: t("global.sources.typeLabel.collectible"), + label: formatInlineTitle(getLocalizedMatch(source.collectible.translations)) + rangeLabel, + }; + + case "page": + return { + href: getLocalizedUrl(`/pages/${source.page.slug}`), + typeLabel: t("global.sources.typeLabel.page"), + label: formatInlineTitle(getLocalizedMatch(source.page.translations)), + }; + + case "folder": + return { + href: getLocalizedUrl(`/folders/${source.folder.slug}`), + typeLabel: t("global.sources.typeLabel.folder"), + label: getLocalizedMatch(source.folder.translations).name, + }; + + default: + return { + href: "/404", + label: `Invalid type ${source["type"]}`, + typeLabel: "Error", + }; + } + }; + return { t, getLocalizedMatch, @@ -185,5 +249,6 @@ export const getI18n = async (locale: string) => { formatMillimeters, formatNumber, formatTimelineDate, + formatEndpointSource, }; }; diff --git a/src/i18n/wordings-keys.ts b/src/i18n/wordings-keys.ts index 7625391..ce368e1 100644 --- a/src/i18n/wordings-keys.ts +++ b/src/i18n/wordings-keys.ts @@ -104,4 +104,11 @@ export type WordingKey = | "timeline.year.during" | "timeline.eventFooter.languages" | "timeline.eventFooter.sources" - | "timeline.eventFooter.note"; + | "timeline.eventFooter.note" + | "global.sources.typeLabel.url" + | "global.sources.typeLabel.page" + | "global.sources.typeLabel.collectible" + | "global.sources.typeLabel.folder" + | "global.sources.typeLabel.collectible.range.page" + | "global.sources.typeLabel.collectible.range.timestamp" + | "global.sources.typeLabel.collectible.range.custom"; diff --git a/src/pages/[locale]/timeline/_components/TimelineSourcesButton.astro b/src/pages/[locale]/timeline/_components/TimelineSourcesButton.astro index 5f65c66..db84cb0 100644 --- a/src/pages/[locale]/timeline/_components/TimelineSourcesButton.astro +++ b/src/pages/[locale]/timeline/_components/TimelineSourcesButton.astro @@ -1,9 +1,9 @@ --- import { Icon } from "astro-icon/components"; +import SourceRow from "components/SourceRow.astro"; import Tooltip from "components/Tooltip.astro"; import { getI18n } from "src/i18n/i18n"; import type { EndpointSource } from "src/shared/payload/payload-sdk"; -import { formatInlineTitle } from "src/utils/format"; interface Props { sources: EndpointSource[]; @@ -11,30 +11,12 @@ interface Props { const { sources } = Astro.props; -const { getLocalizedUrl, getLocalizedMatch, t } = await getI18n(Astro.locals.currentLocale); +const { t } = await getI18n(Astro.locals.currentLocale); ---
- { - sources.map((source) => - source.type === "url" ? ( - - {source.label} - - ) : source.type === "collectible" ? ( - - {formatInlineTitle(getLocalizedMatch(source.collectible.translations))} - - ) : ( - - {formatInlineTitle(getLocalizedMatch(source.page.translations))} - - ) - ) - } + {sources.map((source) => )}
diff --git a/src/shared/payload/payload-sdk.ts b/src/shared/payload/payload-sdk.ts index 447b673..fc74def 100644 --- a/src/shared/payload/payload-sdk.ts +++ b/src/shared/payload/payload-sdk.ts @@ -862,9 +862,6 @@ export interface SectionBlock { blockType: "sectionBlock"; } -declare module "payload" { - export interface GeneratedTypes extends Config {} -} /////////////// CONSTANTS /////////////// @@ -1299,7 +1296,7 @@ export type EndpointFolder = EndpointFolderPreview & { value: EndpointPagePreview; } )[]; - parentPages: ParentPage[]; + parentPages: EndpointSource[]; }; export type EndpointHomeFolder = EndpointFolderPreview & { @@ -1369,13 +1366,7 @@ export type EndpointPage = EndpointPagePreview & { proofreaders: EndpointRecorder[]; toc: TableOfContentEntry[]; })[]; - parentPages: ParentPage[]; -}; - -export type ParentPage = { - slug: string; - collection: Collections; - translations: { language: string; name: string }[]; + parentPages: EndpointSource[]; }; export type EndpointCollectiblePreview = { @@ -1450,7 +1441,7 @@ export type EndpointCollectible = EndpointCollectiblePreview & { }[]; }; }[]; - parentPages: ParentPage[]; + parentPages: EndpointSource[]; }; export type TableOfContentEntry = { @@ -1493,7 +1484,8 @@ export type EndpointSource = | { type: "timestamp"; timestamp: string } | { type: "custom"; translations: { language: string; note: string }[] }; } - | { type: "page"; page: EndpointPagePreview }; + | { type: "page"; page: EndpointPagePreview } + | { type: "folder"; folder: EndpointFolderPreview }; export type PayloadImage = { url: string; @@ -1523,5 +1515,5 @@ export const payload = { getChronologyEvents: async (): Promise => await (await request(payloadApiUrl(Collections.ChronologyEvents, `all`))).json(), getChronologyEventByID: async (id: string): Promise => - await (await request(payloadApiUrl(Collections.ChronologyEvents, id))).json(), + await (await request(payloadApiUrl(Collections.ChronologyEvents, `id/${id}`))).json(), };