Release govoplan-views v0.1.22: unify interface contracts and documentation
This commit is contained in:
@@ -26,6 +26,7 @@ import { FormGrid,
|
||||
ExplorerTree,
|
||||
FormField,
|
||||
IconButton,
|
||||
NavigationPreferenceEditor,
|
||||
SearchableSelect,
|
||||
SegmentedControl,
|
||||
SelectionList,
|
||||
@@ -33,6 +34,7 @@ import { FormGrid,
|
||||
StatusBadge,
|
||||
ToggleSwitch,
|
||||
adminErrorMessage,
|
||||
configurableNavigationItemsForModules,
|
||||
dispatchPlatformViewChanged,
|
||||
i18nMessage,
|
||||
usePlatformLanguage,
|
||||
@@ -134,6 +136,8 @@ export default function ViewsAdminPanel({
|
||||
}) {
|
||||
const surfaces = useViewSurfaces();
|
||||
const modules = usePlatformModules();
|
||||
const navigationItems = useMemo(() => configurableNavigationItemsForModules(modules), [modules]);
|
||||
const navigationProductAreas = useMemo(() => modules.flatMap((module) => module.productAreas ?? []), [modules]);
|
||||
const productAreas = useMemo(() => aggregateProductAreas(modules), [modules]);
|
||||
const { requestDiscard } = useUnsavedChanges();
|
||||
const { translateText } = usePlatformLanguage();
|
||||
@@ -763,6 +767,26 @@ export default function ViewsAdminPanel({
|
||||
</FormField>
|
||||
</div>
|
||||
|
||||
<section className="views-product-area-section">
|
||||
<div className="views-section-heading">
|
||||
<div>
|
||||
<h4>i18n:govoplan-views.navigation_layout</h4>
|
||||
<p className="muted small-note">i18n:govoplan-views.navigation_editor_help</p>
|
||||
</div>
|
||||
</div>
|
||||
<NavigationPreferenceEditor
|
||||
scope="view"
|
||||
items={navigationItems}
|
||||
productAreas={navigationProductAreas}
|
||||
value={draft.presentation.navigation ?? null}
|
||||
disabled={!definitionEditable || busy}
|
||||
onChange={(navigation) => setDraft({
|
||||
...draft,
|
||||
presentation: { ...draft.presentation, navigation }
|
||||
})}
|
||||
/>
|
||||
</section>
|
||||
|
||||
{productAreas.length > 0 && (
|
||||
<ProductAreaEditor
|
||||
areas={productAreas}
|
||||
@@ -1480,6 +1504,7 @@ function ProductAreaEditor({
|
||||
}) {
|
||||
const { translateText } = usePlatformLanguage();
|
||||
const ordered = orderedProductAreas(areas, draft.presentation.productAreaOrder);
|
||||
const customNavigation = draft.presentation.navigation != null;
|
||||
const requiredSurfaceIds = new Set(
|
||||
surfaces.filter((surface) => surface.required).map((surface) => surface.id)
|
||||
);
|
||||
@@ -1518,14 +1543,14 @@ function ProductAreaEditor({
|
||||
<div>
|
||||
<h4>i18n:govoplan-views.product_areas</h4>
|
||||
<p className="muted small-note">
|
||||
i18n:govoplan-views.product_areas_help
|
||||
{customNavigation ? "i18n:govoplan-views.product_areas_custom_navigation_help" : "i18n:govoplan-views.product_areas_help"}
|
||||
</p>
|
||||
</div>
|
||||
<SegmentedControl<"grouped" | "flat">
|
||||
ariaLabel={translateText("i18n:govoplan-views.navigation_layout")}
|
||||
role="group"
|
||||
value={draft.presentation.navigationMode ?? "grouped"}
|
||||
disabled={disabled}
|
||||
disabled={disabled || customNavigation}
|
||||
onChange={(navigationMode) =>
|
||||
updatePresentation({ ...draft.presentation, navigationMode })
|
||||
}
|
||||
@@ -1558,7 +1583,7 @@ function ProductAreaEditor({
|
||||
{ value0: translateText(area.label) }
|
||||
)}
|
||||
maxLength={200}
|
||||
disabled={disabled}
|
||||
disabled={disabled || customNavigation}
|
||||
onChange={(event) => setLabel(area.id, event.target.value)}
|
||||
/>
|
||||
<ToggleSwitch
|
||||
@@ -1575,14 +1600,14 @@ function ProductAreaEditor({
|
||||
label="i18n:govoplan-views.move_up"
|
||||
icon={<ArrowUp size={16} />}
|
||||
variant="ghost"
|
||||
disabled={disabled || index === 0}
|
||||
disabled={disabled || customNavigation || index === 0}
|
||||
onClick={() => move(area.id, -1)}
|
||||
/>
|
||||
<IconButton
|
||||
label="i18n:govoplan-views.move_down"
|
||||
icon={<ArrowDown size={16} />}
|
||||
variant="ghost"
|
||||
disabled={disabled || index === ordered.length - 1}
|
||||
disabled={disabled || customNavigation || index === ordered.length - 1}
|
||||
onClick={() => move(area.id, 1)}
|
||||
/>
|
||||
</div>
|
||||
@@ -1879,6 +1904,7 @@ function aggregateProductAreas(modules: PlatformWebModule[]): ViewProductArea[]
|
||||
|
||||
function defaultPresentation(areas: ViewProductArea[]): ViewPresentation {
|
||||
return {
|
||||
navigation: null,
|
||||
navigationMode: "grouped",
|
||||
productAreaOrder: areas.map((area) => area.id),
|
||||
productAreaLabels: {},
|
||||
@@ -1917,6 +1943,7 @@ function revisionPresentation(
|
||||
): ViewPresentation {
|
||||
const defaults = defaultPresentation(areas);
|
||||
return {
|
||||
navigation: value?.navigation ?? null,
|
||||
navigationMode: value?.navigation_mode ?? defaults.navigationMode,
|
||||
productAreaOrder:
|
||||
value?.product_area_order?.length
|
||||
@@ -1945,6 +1972,7 @@ function orderedProductAreas(
|
||||
|
||||
function presentationKey(value: ViewPresentation): string {
|
||||
return JSON.stringify({
|
||||
navigation: value.navigation ?? null,
|
||||
navigationMode: value.navigationMode ?? "grouped",
|
||||
productAreaOrder: value.productAreaOrder ?? [],
|
||||
productAreaLabels: Object.fromEntries(
|
||||
|
||||
Reference in New Issue
Block a user