fix: preserve landing page section content when toggled off (#838)
* preserve section content when toggled off * Update types.ts * Remove comment on LandingPageLinks enabled property Removed comment about the default visibility of the section. --------- Co-authored-by: Rotimi Best <[email protected]>
This commit is contained in:
co-authored by
Rotimi Best
parent
0dc32b5210
commit
6537613000
@@ -168,7 +168,7 @@ The repository also contains shared packages under `packages/` (for example `pac
|
||||
PUBLIC_SERVER_URL="http://localhost:3002"
|
||||
PRIVATE_SERVER_URL="http://localhost:3002" # used by the SSR auth proxy — required, or login returns "API upstream not configured"
|
||||
PRIVATE_SERVER_KEY="<generate-with-openssl-rand-hex-32>" # must match the API (paste the value generated above)
|
||||
PUBLIC_IS_SELFHOSTED=true
|
||||
PUBLIC_IS_SELFHOSTED=false
|
||||
```
|
||||
|
||||
- Running the background workers? Also create `apps/jobs/.env` (e.g. `cp apps/api/.env apps/jobs/.env`); it needs `REDIS_URL`. The `packages/db/.env` used by the DB scripts is set up in step 6.
|
||||
|
||||
@@ -125,6 +125,7 @@ type LegacyLandingPageJson = {
|
||||
footerText?: string;
|
||||
theme?: OrgLandingPageTheme;
|
||||
embed?: {
|
||||
enabled?: boolean;
|
||||
title?: string;
|
||||
description?: string;
|
||||
code?: string;
|
||||
@@ -138,6 +139,7 @@ type LegacyLandingPageJson = {
|
||||
sandbox?: string;
|
||||
};
|
||||
callout?: {
|
||||
enabled?: boolean;
|
||||
heading?: string;
|
||||
description?: string;
|
||||
action?: {
|
||||
@@ -413,6 +415,7 @@ function normalizeCallout(callout: NonNullable<LegacyLandingPageJson['callout']>
|
||||
}
|
||||
|
||||
return {
|
||||
enabled: callout.enabled !== false,
|
||||
heading,
|
||||
description: normalizeText(callout.description, ''),
|
||||
action: {
|
||||
@@ -468,6 +471,7 @@ function normalizeLinks(raw: unknown): OrgLandingPageLinks | undefined {
|
||||
const classicLearnMoreLabel = normalizeText(raw.classicLearnMoreLabel, '');
|
||||
|
||||
return {
|
||||
enabled: raw.enabled !== false,
|
||||
heading,
|
||||
description: description || undefined,
|
||||
boldVisitLabel: boldVisitLabel || undefined,
|
||||
@@ -541,6 +545,7 @@ export function normalizeLandingPageSettings(value: unknown): OrgLandingPageJson
|
||||
footer: resolveFooterConfig(landingPage),
|
||||
embed: landingPage.embed
|
||||
? {
|
||||
enabled: landingPage.embed.enabled !== false,
|
||||
title: normalizeText(landingPage.embed.title, 'Section title'),
|
||||
description: normalizeText(landingPage.embed.description, ''),
|
||||
code: normalizeEmbedCode(landingPage.embed),
|
||||
@@ -587,6 +592,7 @@ export function normalizeLandingPageSettings(value: unknown): OrgLandingPageJson
|
||||
footer: resolveFooterConfig(landingPage),
|
||||
embed: landingPage.embed
|
||||
? {
|
||||
enabled: landingPage.embed.enabled !== false,
|
||||
title: normalizeText(landingPage.embed.title, 'Section title'),
|
||||
description: normalizeText(landingPage.embed.description, ''),
|
||||
code: normalizeEmbedCode(landingPage.embed)
|
||||
@@ -624,6 +630,7 @@ export function normalizeLandingPageSettings(value: unknown): OrgLandingPageJson
|
||||
footer: resolveFooterConfig(landingPage),
|
||||
embed: landingPage.embed
|
||||
? {
|
||||
enabled: landingPage.embed.enabled !== false,
|
||||
title: normalizeText(landingPage.embed.title, 'Section title'),
|
||||
description: normalizeText(landingPage.embed.description, ''),
|
||||
code: normalizeEmbedCode(landingPage.embed),
|
||||
|
||||
+4
-12
@@ -33,6 +33,7 @@
|
||||
}
|
||||
|
||||
const callout: OrgLandingPageCallout = {
|
||||
enabled: true,
|
||||
heading: t.get('settings.landing_page.editor.callout.heading_default'),
|
||||
description: '',
|
||||
action: {
|
||||
@@ -51,16 +52,7 @@
|
||||
}
|
||||
|
||||
function setCalloutEnabled(enabled: boolean) {
|
||||
if (!enabled) {
|
||||
settings = {
|
||||
...settings,
|
||||
callout: undefined
|
||||
};
|
||||
markDirty();
|
||||
return;
|
||||
}
|
||||
|
||||
setter(ensureCallout(), 'callout');
|
||||
setter({ ...ensureCallout(), enabled }, 'callout');
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -71,13 +63,13 @@
|
||||
<div class="space-y-6">
|
||||
<Field.Field orientation="horizontal">
|
||||
<Switch
|
||||
checked={Boolean(settings.callout)}
|
||||
checked={settings.callout?.enabled ?? false}
|
||||
onCheckedChange={(checked) => setCalloutEnabled(checked === true)}
|
||||
/>
|
||||
<Field.Label>{$t('settings.landing_page.editor.callout.toggle')}</Field.Label>
|
||||
</Field.Field>
|
||||
|
||||
{#if settings.callout}
|
||||
{#if settings.callout?.enabled}
|
||||
<Field.Field>
|
||||
<div class="flex items-center justify-between">
|
||||
<Field.Label>{$t('settings.landing_page.editor.callout.heading')}</Field.Label>
|
||||
|
||||
+9
-12
@@ -34,6 +34,7 @@
|
||||
}
|
||||
|
||||
const embed = {
|
||||
enabled: true,
|
||||
title: t.get('settings.landing_page.editor.embed.title'),
|
||||
description: '',
|
||||
code: '',
|
||||
@@ -50,16 +51,7 @@
|
||||
}
|
||||
|
||||
function setEmbedEnabled(enabled: boolean) {
|
||||
if (!enabled) {
|
||||
settings = {
|
||||
...settings,
|
||||
embed: undefined
|
||||
};
|
||||
markDirty();
|
||||
return;
|
||||
}
|
||||
|
||||
setter(ensureEmbed(), 'embed');
|
||||
setter({ ...ensureEmbed(), enabled }, 'embed');
|
||||
}
|
||||
|
||||
function updateSecondaryAction(label: string, href: string) {
|
||||
@@ -83,11 +75,15 @@
|
||||
|
||||
<div class="space-y-6">
|
||||
<Field.Field orientation="horizontal">
|
||||
<Switch checked={Boolean(settings.embed)} onCheckedChange={(checked) => setEmbedEnabled(checked === true)} />
|
||||
<Switch
|
||||
checked={settings.embed?.enabled ?? false}
|
||||
onCheckedChange={(checked) => setEmbedEnabled(checked === true)}
|
||||
/>
|
||||
<Field.Label>{$t('settings.landing_page.editor.embed.toggle')}</Field.Label>
|
||||
</Field.Field>
|
||||
|
||||
{#if settings.embed}
|
||||
{#if settings.embed?.enabled}
|
||||
<div class="pb-5">
|
||||
<Field.Field>
|
||||
<div class="flex items-center justify-between">
|
||||
<Field.Label>{$t('settings.landing_page.editor.embed.title')}</Field.Label>
|
||||
@@ -140,6 +136,7 @@
|
||||
onLabelInput={(value) => updateSecondaryAction(value, settings.embed.secondaryAction?.href ?? '')}
|
||||
onHrefInput={(value) => updateSecondaryAction(settings.embed.secondaryAction?.label ?? '', value)}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</Field.Set>
|
||||
|
||||
+7
-8
@@ -54,6 +54,7 @@
|
||||
}
|
||||
|
||||
const links: NonNullable<OrgLandingPageJson['links']> = {
|
||||
enabled: true,
|
||||
heading: t.get('settings.landing_page.editor.links.heading_default'),
|
||||
description: '',
|
||||
boldVisitLabel: t.get('settings.landing_page.editor.links.bold_visit_default'),
|
||||
@@ -90,16 +91,11 @@
|
||||
}
|
||||
|
||||
function setLinksEnabled(enabled: boolean) {
|
||||
if (!enabled) {
|
||||
settings = {
|
||||
...settings,
|
||||
links: undefined
|
||||
links: { ...ensureLinks(), enabled }
|
||||
};
|
||||
markDirty();
|
||||
return;
|
||||
}
|
||||
|
||||
ensureLinks();
|
||||
}
|
||||
|
||||
function addCard() {
|
||||
@@ -137,11 +133,14 @@
|
||||
|
||||
<div class="space-y-6">
|
||||
<Field.Field orientation="horizontal">
|
||||
<Switch checked={Boolean(settings.links)} onCheckedChange={(checked) => setLinksEnabled(checked === true)} />
|
||||
<Switch
|
||||
checked={settings.links?.enabled ?? false}
|
||||
onCheckedChange={(checked) => setLinksEnabled(checked === true)}
|
||||
/>
|
||||
<Field.Label>{$t('settings.landing_page.editor.links.toggle')}</Field.Label>
|
||||
</Field.Field>
|
||||
|
||||
{#if settings.links}
|
||||
{#if settings.links?.enabled}
|
||||
<Field.Field>
|
||||
<Field.Label>{$t('settings.landing_page.editor.links.heading')}</Field.Label>
|
||||
<Input
|
||||
|
||||
@@ -50,6 +50,7 @@ export type OrgLandingPageFooterConfig = {
|
||||
};
|
||||
|
||||
export interface OrgLandingPageEmbed {
|
||||
enabled: boolean;
|
||||
title: string;
|
||||
description?: string;
|
||||
code: string;
|
||||
@@ -60,6 +61,7 @@ export interface OrgLandingPageEmbed {
|
||||
}
|
||||
|
||||
export interface OrgLandingPageCallout {
|
||||
enabled: boolean;
|
||||
heading: string;
|
||||
description: string;
|
||||
action: {
|
||||
@@ -88,6 +90,7 @@ export interface OrgLandingPageLinkCard {
|
||||
}
|
||||
|
||||
export interface OrgLandingPageLinks {
|
||||
enabled: boolean;
|
||||
heading: string;
|
||||
description?: string;
|
||||
boldVisitLabel?: string;
|
||||
|
||||
@@ -153,7 +153,7 @@ Composable page shell used across dashboard list and settings screens. Import as
|
||||
The bar also sits at `z-50`, matching the editor root so it paints above editor content (later in DOM wins the tie) while staying below body-portaled dialogs and sheets. Its shadow appears only while it is pinned away from its flow position, tracked by an `IntersectionObserver` on a 1px sentinel rendered as its next sibling.
|
||||
|
||||
| Prop | Description |
|
||||
| -------------- | -------------------------------------------------------- |
|
||||
| -------------- | ------------------------------------------------------ |
|
||||
| `hasChanges` | Enables Save and Discard when the form is dirty |
|
||||
| `loading` | Shows loading state on Save |
|
||||
| `disabled` | Disables Save only (e.g. while not initialized) |
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
`;
|
||||
</script>
|
||||
|
||||
{#if callout}
|
||||
{#if callout && callout.enabled !== false}
|
||||
<EditableLandingSection sectionKey="callout">
|
||||
<section
|
||||
class={sectionClasses[variant]}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
} = $props();
|
||||
</script>
|
||||
|
||||
{#if embed}
|
||||
{#if embed && embed.enabled !== false}
|
||||
<EditableLandingSection sectionKey="embed">
|
||||
{#if variant === 'terminal'}
|
||||
<section class="ui:py-24 ui:px-6" style="border-top: 1px solid #1c1f28; background: #06070a;">
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if links && links.cards.length > 0}
|
||||
{#if links && links.enabled !== false && links.cards.length > 0}
|
||||
<EditableLandingSection sectionKey="links">
|
||||
{#if variant === 'minimal'}
|
||||
<section class="ui:py-20 ui:px-4">
|
||||
|
||||
@@ -81,17 +81,17 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{#if links && links.cards.length > 0}
|
||||
{#if links && links.enabled !== false && links.cards.length > 0}
|
||||
<div class="plus-row"></div>
|
||||
<OrgLandingPageLinks {links} {labels} variant="saas" />
|
||||
{/if}
|
||||
|
||||
{#if embed}
|
||||
{#if embed && embed.enabled !== false}
|
||||
<div class="plus-row"></div>
|
||||
<OrgLandingPageEmbed {embed} {labels} variant="saas" />
|
||||
{/if}
|
||||
|
||||
{#if callout}
|
||||
{#if callout && callout.enabled !== false}
|
||||
<div class="plus-row"></div>
|
||||
<OrgLandingPageCallout {callout} {labels} variant="saas" />
|
||||
{/if}
|
||||
|
||||
@@ -91,6 +91,7 @@ export type OrgLandingPageFooterConfig = {
|
||||
};
|
||||
};
|
||||
export type LandingPageEmbed = {
|
||||
enabled?: boolean;
|
||||
title: string;
|
||||
description?: string;
|
||||
code: string;
|
||||
@@ -101,6 +102,7 @@ export type LandingPageEmbed = {
|
||||
};
|
||||
|
||||
export type LandingPageCallout = {
|
||||
enabled?: boolean;
|
||||
heading: string;
|
||||
description: string;
|
||||
action: {
|
||||
@@ -129,6 +131,7 @@ export type LandingPageLinkCard = {
|
||||
};
|
||||
|
||||
export type LandingPageLinks = {
|
||||
enabled?: boolean;
|
||||
heading: string;
|
||||
description?: string;
|
||||
/** Bold template card footer chip (e.g. Visit). */
|
||||
|
||||
Reference in New Issue
Block a user