chore: sync GovOPlaN module split state
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { Button } from "@govoplan/core-webui";
|
||||
import { Dialog } from "@govoplan/core-webui";
|
||||
import { DismissibleAlert } from "@govoplan/core-webui";
|
||||
import { DismissibleAlert, i18nMessage } from "@govoplan/core-webui";
|
||||
import type { TemplateNamespace, TemplatePlaceholder, UndefinedPlaceholder } from "../utils/templatePlaceholders";
|
||||
|
||||
export type TemplateFieldOption = {
|
||||
@@ -16,14 +16,14 @@ export function TemplateFieldChipList({
|
||||
empty,
|
||||
disabled = false,
|
||||
onInsert
|
||||
}: {
|
||||
namespace: TemplateNamespace;
|
||||
fields: TemplateFieldOption[];
|
||||
usedPlaceholders?: TemplatePlaceholder[];
|
||||
empty: string;
|
||||
disabled?: boolean;
|
||||
onInsert: (namespace: TemplateNamespace, name: string) => void;
|
||||
}) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}: {namespace: TemplateNamespace;fields: TemplateFieldOption[];usedPlaceholders?: TemplatePlaceholder[];empty: string;disabled?: boolean;onInsert: (namespace: TemplateNamespace, name: string) => void;}) {
|
||||
if (fields.length === 0) return <p className="muted">{empty}</p>;
|
||||
return (
|
||||
<div className="field-chip-list">
|
||||
@@ -35,46 +35,46 @@ export function TemplateFieldChipList({
|
||||
className={`field-chip field-chip-button ${used ? "used" : ""}`}
|
||||
key={`${namespace}:${field.name}`}
|
||||
disabled={disabled}
|
||||
onClick={() => onInsert(namespace, field.name)}
|
||||
>
|
||||
onClick={() => onInsert(namespace, field.name)}>
|
||||
|
||||
<span className="field-chip-namespace">{namespace}</span><span title={field.label !== field.name ? field.label : undefined}>{field.name}</span>
|
||||
</button>
|
||||
);
|
||||
</button>);
|
||||
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
</div>);
|
||||
|
||||
}
|
||||
|
||||
export function UndefinedPlaceholderList({
|
||||
items,
|
||||
empty = "No undefined placeholders detected.",
|
||||
empty = "i18n:govoplan-campaign.no_undefined_placeholders_detected.1cbdf41b",
|
||||
onSelect
|
||||
}: {
|
||||
items: UndefinedPlaceholder[];
|
||||
empty?: string;
|
||||
onSelect: (item: UndefinedPlaceholder) => void;
|
||||
}) {
|
||||
|
||||
|
||||
|
||||
|
||||
}: {items: UndefinedPlaceholder[];empty?: string;onSelect: (item: UndefinedPlaceholder) => void;}) {
|
||||
if (items.length === 0) return <p className="muted">{empty}</p>;
|
||||
return (
|
||||
<div className="field-chip-list">
|
||||
{items.map((item) => (
|
||||
<button
|
||||
type="button"
|
||||
className="field-chip field-chip-button undefined"
|
||||
key={`${item.raw}:${item.reason}`}
|
||||
onClick={() => onSelect(item)}
|
||||
>
|
||||
{items.map((item) =>
|
||||
<button
|
||||
type="button"
|
||||
className="field-chip field-chip-button undefined"
|
||||
key={`${item.raw}:${item.reason}`}
|
||||
onClick={() => onSelect(item)}>
|
||||
|
||||
{item.display}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
)}
|
||||
</div>);
|
||||
|
||||
}
|
||||
|
||||
export function UndefinedPlaceholderDecisionDialog({
|
||||
field,
|
||||
contextLabel = "template",
|
||||
removeLabel = "Remove placeholder",
|
||||
removeLabel = "i18n:govoplan-campaign.remove_placeholder.3f575c72",
|
||||
localFields = [],
|
||||
globalFields = [],
|
||||
onCancel,
|
||||
@@ -82,23 +82,23 @@ export function UndefinedPlaceholderDecisionDialog({
|
||||
onReplace,
|
||||
onAddField,
|
||||
addDisabled = false
|
||||
}: {
|
||||
field: UndefinedPlaceholder | null;
|
||||
contextLabel?: string;
|
||||
removeLabel?: string;
|
||||
localFields?: TemplateFieldOption[];
|
||||
globalFields?: TemplateFieldOption[];
|
||||
onCancel: () => void;
|
||||
onRemove: (field: UndefinedPlaceholder) => void;
|
||||
onReplace?: (field: UndefinedPlaceholder, namespace: TemplateNamespace, name: string) => void;
|
||||
onAddField: (field: UndefinedPlaceholder) => void;
|
||||
addDisabled?: boolean;
|
||||
}) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}: {field: UndefinedPlaceholder | null;contextLabel?: string;removeLabel?: string;localFields?: TemplateFieldOption[];globalFields?: TemplateFieldOption[];onCancel: () => void;onRemove: (field: UndefinedPlaceholder) => void;onReplace?: (field: UndefinedPlaceholder, namespace: TemplateNamespace, name: string) => void;onAddField: (field: UndefinedPlaceholder) => void;addDisabled?: boolean;}) {
|
||||
const replacementOptions = useMemo(
|
||||
() => [
|
||||
...localFields.map((item) => ({ namespace: "local" as const, ...item })),
|
||||
...globalFields.map((item) => ({ namespace: "global" as const, ...item }))
|
||||
],
|
||||
...localFields.map((item) => ({ namespace: "local" as const, ...item })),
|
||||
...globalFields.map((item) => ({ namespace: "global" as const, ...item }))],
|
||||
|
||||
[globalFields, localFields]
|
||||
);
|
||||
const [replacement, setReplacement] = useState("");
|
||||
@@ -121,42 +121,42 @@ export function UndefinedPlaceholderDecisionDialog({
|
||||
return (
|
||||
<Dialog
|
||||
open={Boolean(field)}
|
||||
title="Undefined field reference"
|
||||
closeLabel="Return to editing"
|
||||
title="i18n:govoplan-campaign.undefined_field_reference.4ff8e266"
|
||||
closeLabel="i18n:govoplan-campaign.return_to_editing.37d4a5f0"
|
||||
className="template-action-dialog"
|
||||
onClose={onCancel}
|
||||
footer={field ? (
|
||||
<>
|
||||
<Button onClick={onCancel}>Continue editing</Button>
|
||||
footer={field ?
|
||||
<>
|
||||
<Button onClick={onCancel}>i18n:govoplan-campaign.continue_editing.b101465f</Button>
|
||||
<Button onClick={() => onRemove(field)}>{removeLabel}</Button>
|
||||
{onReplace && replacementOptions.length > 0 && <Button onClick={replaceWithSelected}>Replace</Button>}
|
||||
<Button variant="primary" onClick={() => onAddField(field)} disabled={!field.name || field.reason === "invalid-namespace" || addDisabled}>Add field</Button>
|
||||
</>
|
||||
) : undefined}
|
||||
>
|
||||
{field && (
|
||||
<>
|
||||
<p>The {contextLabel} uses <code>{`{{${field.raw}}}`}</code>, but it cannot be matched to a known field.</p>
|
||||
{field.reason === "invalid-namespace" && (
|
||||
<DismissibleAlert tone="warning">Use the namespace <code>global:</code> or <code>local:</code>.</DismissibleAlert>
|
||||
)}
|
||||
{field.reason === "missing-field" && (
|
||||
<p className="muted">You can add <strong>{field.name}</strong> as a campaign field, remove this placeholder, or continue editing.</p>
|
||||
)}
|
||||
{onReplace && replacementOptions.length > 0 && (
|
||||
<label className="template-replacement-field">
|
||||
<span>Replace by existing field</span>
|
||||
{onReplace && replacementOptions.length > 0 && <Button onClick={replaceWithSelected}>i18n:govoplan-campaign.replace.a7cf7b25</Button>}
|
||||
<Button variant="primary" onClick={() => onAddField(field)} disabled={!field.name || field.reason === "invalid-namespace" || addDisabled}>i18n:govoplan-campaign.add_field.039c6315</Button>
|
||||
</> :
|
||||
undefined}>
|
||||
|
||||
{field &&
|
||||
<>
|
||||
<p>i18n:govoplan-campaign.the.93ef0dd8 {contextLabel} uses <code>{i18nMessage("i18n:govoplan-campaign.value.91317e63", { value0: field.raw })}</code>i18n:govoplan-campaign.but_it_cannot_be_matched_to_a_known_field.e75c4dde</p>
|
||||
{field.reason === "invalid-namespace" &&
|
||||
<DismissibleAlert tone="warning">i18n:govoplan-campaign.use_the_namespace.a4c2669d <code>global:</code> or <code>local:</code>.</DismissibleAlert>
|
||||
}
|
||||
{field.reason === "missing-field" &&
|
||||
<p className="muted">i18n:govoplan-campaign.you_can_add.66093419 <strong>{field.name}</strong> i18n:govoplan-campaign.as_a_campaign_field_remove_this_placeholder_or_c.6bf2dea8</p>
|
||||
}
|
||||
{onReplace && replacementOptions.length > 0 &&
|
||||
<label className="template-replacement-field">
|
||||
<span>i18n:govoplan-campaign.replace_by_existing_field.ee3dc0eb</span>
|
||||
<select value={effectiveReplacement} onChange={(event) => setReplacement(event.target.value)}>
|
||||
{replacementOptions.map((option) => (
|
||||
<option key={`${option.namespace}:${option.name}`} value={`${option.namespace}:${option.name}`}>
|
||||
{replacementOptions.map((option) =>
|
||||
<option key={`${option.namespace}:${option.name}`} value={`${option.namespace}:${option.name}`}>
|
||||
{option.namespace}:{option.label || option.name}
|
||||
</option>
|
||||
))}
|
||||
)}
|
||||
</select>
|
||||
</label>
|
||||
)}
|
||||
}
|
||||
</>
|
||||
)}
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
}
|
||||
</Dialog>);
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user