improve sources and parent pages

This commit is contained in:
DrMint 2024-03-22 23:14:47 +01:00
parent 0c4d5e4007
commit 1d5e34f1a6
10 changed files with 131 additions and 99 deletions

View File

@ -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)

View File

@ -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<typeof Html>["openGraph"];
parentPages?: ParentPage[];
parentPages?: EndpointSource[];
hideFooterLinks?: boolean;
backgroundImage?: PayloadImage | undefined;
}

View File

@ -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;
}

View File

@ -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,10 +24,12 @@ const { t } = await getI18n(Astro.locals.currentLocale);
<Tooltip trigger="click">
<div id="tooltip-content" slot="tooltip-content">
<p>{t("header.nav.parentPages.tooltip")}</p>
<div>
{parentPages.map((parentPage) => (
<ParentPageLink parentPage={parentPage} />
<SourceRow source={parentPage} />
))}
</div>
</div>
<div class="pressable-label">
<Icon name="material-symbols:keyboard-return" />
<p>
@ -44,7 +46,14 @@ const { t } = await getI18n(Astro.locals.currentLocale);
<style>
#tooltip-content {
display: grid;
gap: 1em;
> p {
margin-bottom: 1em;
}
> div {
display: flex;
flex-direction: column;
gap: 0.5em;
}
}
</style>

View File

@ -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 ------------------------------------------- */}
<a href={href}>
<a href={href} target={target} rel={rel}>
<div class="pressable-label">
<Icon name="material-symbols:keyboard-return" />
<p>
<span>{collectionLabel}</span>
{translation.name}
<span>{typeLabel}</span>
{label}
</p>
</div>
</a>

View File

@ -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 ------------------------------------------- */}
<a href={href}><div>{collectionLabel}</div><p>{translation.name}</p></a>
<a href={href} target={target} rel={rel}><div>{typeLabel}</div><p>{label}</p></a>
{/* ------------------------------------------- CSS -------------------------------------------- */}

View File

@ -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,
};
};

View File

@ -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";

View File

@ -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);
---
<Tooltip trigger="click">
<div id="tooltip-content" slot="tooltip-content">
{
sources.map((source) =>
source.type === "url" ? (
<a class="pressable-link" href={source.url} target={"_blank"} rel={"noopener noreferrer"}>
{source.label}
</a>
) : source.type === "collectible" ? (
<a
class="pressable-link"
href={getLocalizedUrl(`/collectibles/${source.collectible.slug}`)}>
{formatInlineTitle(getLocalizedMatch(source.collectible.translations))}
</a>
) : (
<a class="pressable-link" href={getLocalizedUrl(`/pages/${source.page.slug}`)}>
{formatInlineTitle(getLocalizedMatch(source.page.translations))}
</a>
)
)
}
{sources.map((source) => <SourceRow source={source} />)}
</div>
<div class="pressable-label">
<Icon name="material-symbols:edit-note" />

View File

@ -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<EndpointChronologyEvent[]> =>
await (await request(payloadApiUrl(Collections.ChronologyEvents, `all`))).json(),
getChronologyEventByID: async (id: string): Promise<EndpointChronologyEvent> =>
await (await request(payloadApiUrl(Collections.ChronologyEvents, id))).json(),
await (await request(payloadApiUrl(Collections.ChronologyEvents, `id/${id}`))).json(),
};