fix(foundry): make map objects true layer toggles

This commit is contained in:
Codex
2026-07-22 10:33:58 +03:00
parent ca26702047
commit b8fc4c5ba1
4 changed files with 111 additions and 24 deletions
+43 -13
View File
@@ -268,6 +268,10 @@ function initialSubjectState(bindings: MapDataProductBinding[], saved: MapSubjec
})) as Record<string, MapSubjectState>;
}
function hasSubjectWindowControls(profile: MapPresentationProfile) {
return profile.facets.some((facet) => facet.counter || facet.filterable);
}
const logarithmicControlValue = (value: number) => Math.log10(Math.max(Number.MIN_VALUE, value));
const valueFromLogarithmicControl = (value: number) => Math.max(1, Math.round(10 ** value));
const formatMetricDistance = (value: number) => value >= 1000
@@ -628,9 +632,14 @@ export const MapFixturePreview = forwardRef<MapFixturePreviewHandle, {
visible: true,
filters: {},
window: defaultSubjectWindowState(0),
}).map((state) => {
const summary = presentationSummaries.find((candidate) => candidate.bindingId === state.bindingId);
return summary && !hasSubjectWindowControls(summary.profile)
? { ...state, window: { ...state.window, open: false } }
: state;
}),
}),
}), [dataProductBindings, mapCamera, mapHeight, mapSettings, pinBindings, presentationProfiles, subjectStates]);
}), [dataProductBindings, mapCamera, mapHeight, mapSettings, pinBindings, presentationProfiles, presentationSummaries, subjectStates]);
const updateSubjectState = (bindingId: string, update: (state: MapSubjectState) => MapSubjectState) => {
setSubjectStates((current) => {
@@ -656,6 +665,10 @@ export const MapFixturePreview = forwardRef<MapFixturePreviewHandle, {
});
};
const toggleSubjectVisibility = (bindingId: string) => {
updateSubjectState(bindingId, (state) => ({ ...state, visible: !state.visible }));
};
const openSubjectWindow = (bindingId: string) => {
const nextZIndex = Math.max(20, layersWindowZIndex, ...Object.values(subjectStates).map((state) => state.window.zIndex)) + 1;
updateSubjectState(bindingId, (state) => ({
@@ -1201,21 +1214,38 @@ export const MapFixturePreview = forwardRef<MapFixturePreviewHandle, {
{presentationSummaries.map((summary) => {
const state = subjectStates[summary.bindingId];
const visibleCount = filteredTargets.filter((target) => target.bindingId === summary.bindingId && target.renderable).length;
const visible = state?.visible !== false;
const hasControls = hasSubjectWindowControls(summary.profile);
return (
<button
type="button"
role="menuitem"
<div
className="catalog-map-fixture__objects-menu-item"
key={summary.bindingId}
data-open={state?.window.open || undefined}
onClick={() => {
openSubjectWindow(summary.bindingId);
close();
}}
data-visible={visible || undefined}
data-open={hasControls && state?.window.open || undefined}
>
<span>{summary.displayName}</span>
<small>{state?.visible === false || visibleCount === 0 ? "на карте: 0" : `на карте: ${visibleCount}`}{state?.window.open ? " · окно открыто" : ""}</small>
</button>
<button
type="button"
role="menuitemcheckbox"
aria-checked={visible}
className="catalog-map-fixture__objects-menu-toggle"
onClick={() => toggleSubjectVisibility(summary.bindingId)}
>
<span>{summary.displayName}</span>
<small>{visible ? `на карте: ${visibleCount}` : `слой скрыт · ${summary.total} объектов`}</small>
</button>
{hasControls ? (
<IconButton
label={`Фильтры и счётчики: ${summary.displayName}`}
role="menuitem"
aria-pressed={state?.window.open || false}
data-active={state?.window.open || undefined}
onClick={() => {
openSubjectWindow(summary.bindingId);
close();
}}
><Icon name="settings" /></IconButton>
) : null}
</div>
);
})}
{!presentationSummaries.length ? <small className="catalog-map-fixture__objects-menu-empty">Нет подключённых объектов.</small> : null}
@@ -1229,7 +1259,7 @@ export const MapFixturePreview = forwardRef<MapFixturePreviewHandle, {
{presentationSummaries.map((summary) => {
const state = subjectStates[summary.bindingId];
if (!state?.window.open) return null;
if (!state?.window.open || !hasSubjectWindowControls(summary.profile)) return null;
const visibleCount = filteredTargets.filter((target) => target.bindingId === summary.bindingId && target.renderable).length;
return (
<WorkspaceWindow