Skip to content

Commit 5f95893

Browse files
Merge 9f84f49 into c91ece3
2 parents c91ece3 + 9f84f49 commit 5f95893

27 files changed

Lines changed: 4105 additions & 143 deletions

apps/belis/desktop/src/components/commons/BelisMapWrapper.tsx

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { useEffect, useMemo, useRef, useState, useCallback } from "react";
22
import { CarmaMap, DatasheetLayout } from "@carma-mapping/core";
33
import { useDispatch, useSelector } from "react-redux";
4-
import { setSelectedFeature } from "../../store/slices/featureCollection";
4+
import {
5+
setSelectedFeature,
6+
setFeatureLoading,
7+
} from "../../store/slices/featureCollection";
58
import {
69
getActiveBackgroundLayer,
710
getBackgroundLayerOpacities,
@@ -27,6 +30,8 @@ import type maplibregl from "maplibre-gl";
2730
import BelisDatasheetView from "../ui/BelisDatasheetView";
2831
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
2932
import { faMap } from "@fortawesome/free-solid-svg-icons";
33+
import { getJWT } from "../../store/slices/auth";
34+
import { FeatureType, fetchFeatureById } from "../../helper/apiMethods";
3035

3136
const LIST_WIDTH = 300;
3237

@@ -35,9 +40,11 @@ const MINI_MAP_DEBUGGING = false;
3540

3641
const BelisMapLibWrapper = ({ mapSizes }) => {
3742
const dispatch: AppDispatch = useDispatch();
43+
const jwt = useSelector(getJWT);
3844
const { map } = useLibreContext();
39-
const { selectedFeature, rawFeature } = useMapSelection();
45+
const { selectedFeature, rawFeature, selectedFeatureId } = useMapSelection();
4046
const { closeDatasheet } = useDatasheet();
47+
const [fetchedFeatureData, setFetchedFeatureData] = useState<any>(null);
4148

4249
const activeBackgroundLayer = useSelector(getActiveBackgroundLayer);
4350
const backgroundLayerOpacities = useSelector(getBackgroundLayerOpacities);
@@ -119,6 +126,44 @@ const BelisMapLibWrapper = ({ mapSizes }) => {
119126

120127
const mapWidth = mapSizes.width - LIST_WIDTH;
121128

129+
useEffect(() => {
130+
const fetchData = async () => {
131+
if (!jwt || !selectedFeatureId?.id) {
132+
setFetchedFeatureData(null);
133+
return;
134+
}
135+
136+
// Get sourceLayer from selectedFeatureId or rawFeature
137+
const sourceLayer = selectedFeatureId.sourceLayer;
138+
139+
console.log("xxx BelisMa Selection:", {
140+
id: selectedFeatureId.id,
141+
sourceLayer,
142+
});
143+
144+
if (sourceLayer && selectedFeatureId.id) {
145+
dispatch(setFeatureLoading(true));
146+
try {
147+
const fullData = await fetchFeatureById(
148+
jwt,
149+
selectedFeatureId.id as number,
150+
sourceLayer as FeatureType
151+
);
152+
console.log("xxx Fetched full data:", fullData);
153+
// Pass full data - forms will extract what they need internally
154+
setFetchedFeatureData(fullData);
155+
} catch (error) {
156+
console.error("xxx Failed to fetch feature:", error);
157+
setFetchedFeatureData(null);
158+
} finally {
159+
dispatch(setFeatureLoading(false));
160+
}
161+
}
162+
};
163+
164+
fetchData();
165+
}, [selectedFeatureId, jwt]);
166+
122167
return (
123168
<div
124169
className="relative flex"
@@ -197,6 +242,8 @@ const BelisMapLibWrapper = ({ mapSizes }) => {
197242
<BelisDatasheetView
198243
feature={selectedFeature}
199244
rawFeature={rawFeature}
245+
fetchedData={fetchedFeatureData}
246+
featureType={selectedFeatureId?.sourceLayer}
200247
/>
201248
</div>
202249
}

apps/belis/desktop/src/components/commons/Layout.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
import { Outlet } from "react-router-dom";
2+
import PhotoLightbox from "../ui/PhotoLightbox";
23
import TopNavbar from "./TopNavbar";
34

45
const Layout = () => {
56
return (
67
<div className="bg-[#F1F1F1] flex flex-col w-full h-full min-h-screen overflow-clip">
8+
<PhotoLightbox
9+
reactModalStyleOverride={{ overlay: { zIndex: 60000000 } }}
10+
animationDuration={200}
11+
/>
712
<TopNavbar />
813
<div className="w-full flex-1">
914
<Outlet />

apps/belis/desktop/src/components/pages/KeyTablesPage.tsx

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
import { useEffect, useState, useRef, useCallback } from "react";
2-
import { fetchAllKeyTables, keyTableFetchers } from "../../helper/apiMethods";
2+
import { keyTableFetchers } from "../../helper/apiMethods";
33
import { AppDispatch } from "../../store";
44
import { useDispatch, useSelector } from "react-redux";
55
import { getJWT } from "../../store/slices/auth";
66
import { useSyncOptional } from "@carma-providers/syncing";
77
import {
88
setKeyTablesData,
9-
setKeyTablesErrors,
10-
setKeyTablesLoading,
119
getKeyTablesData,
1210
getKeyTablesErrors,
1311
getKeyTablesLoading,
14-
getKeyTablesFetched,
1512
} from "../../store/slices/keyTables";
1613
import { Spin, Alert, Modal, message, List } from "antd";
1714
import KeyTableDataGroups from "../ui/KeyTableDataGroups";
@@ -35,7 +32,6 @@ const KeyTablesPage = () => {
3532
const data = useSelector(getKeyTablesData);
3633
const errors = useSelector(getKeyTablesErrors);
3734
const loading = useSelector(getKeyTablesLoading);
38-
const fetched = useSelector(getKeyTablesFetched);
3935
const [selectedTable, setSelectedTable] = useState<string | null>(null);
4036
const [selectedItem, setSelectedItem] = useState<SelectedItem | null>(null);
4137
const [isFirstColumnCollapsed, setIsFirstColumnCollapsed] = useState(false);
@@ -70,25 +66,6 @@ const KeyTablesPage = () => {
7066
}
7167
};
7268

73-
useEffect(() => {
74-
if (fetched) return;
75-
76-
const fetchData = async () => {
77-
if (!storedJWT) return;
78-
79-
dispatch(setKeyTablesLoading(true));
80-
try {
81-
const { data, errors } = await fetchAllKeyTables(storedJWT);
82-
dispatch(setKeyTablesData(data));
83-
dispatch(setKeyTablesErrors(errors));
84-
} catch (error) {
85-
console.error("Failed to fetch key tables:", error);
86-
} finally {
87-
dispatch(setKeyTablesLoading(false));
88-
}
89-
};
90-
fetchData();
91-
}, []);
9269

9370
// Select first table by default when data loads (sorted alphabetically to match display)
9471
useEffect(() => {

apps/belis/desktop/src/components/pages/MainPage.tsx

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
1-
import { useContext } from "react";
1+
import { useContext, useEffect } from "react";
22
import BelisMapLibWrapper from "../commons/BelisMapWrapper";
33
import { useSelector, useDispatch } from "react-redux";
44
import { getJWT } from "../../store/slices/auth";
5+
import { fetchAllKeyTables } from "../../helper/apiMethods";
6+
import {
7+
setKeyTablesData,
8+
setKeyTablesErrors,
9+
setKeyTablesLoading,
10+
getKeyTablesFetched,
11+
getKeyTablesLoading,
12+
} from "../../store/slices/keyTables";
13+
import { message, Spin } from "antd";
514
import { CustomCard } from "../commons/CustomCard";
615
import { useWindowSize } from "@react-hook/window-size";
716
import {
@@ -15,6 +24,7 @@ import {
1524
setDone,
1625
setFeatureCollection,
1726
setFocusModeActive,
27+
getFeatureLoading,
1828
} from "../../store/slices/featureCollection";
1929
import { TopicMapContext } from "react-cismap/contexts/TopicMapContextProvider";
2030
import { useDatasheet } from "@carma-mapping/engines/maplibre";
@@ -40,8 +50,38 @@ const MainPage = () => {
4050
const inPaleMode = useSelector(isInPaleMode);
4151
const inSearchMode = useSelector(isInSearchMode);
4252
const zoom = useSelector(getZoom);
53+
const keyTablesFetched = useSelector(getKeyTablesFetched);
54+
const keyTablesLoading = useSelector(getKeyTablesLoading);
55+
const featureLoading = useSelector(getFeatureLoading);
4356

4457
const { isDatasheetOpen } = useDatasheet();
58+
59+
// Fetch key tables data on mount
60+
useEffect(() => {
61+
if (keyTablesFetched) return;
62+
63+
const fetchData = async () => {
64+
if (!storedJWT) return;
65+
66+
dispatch(setKeyTablesLoading(true));
67+
try {
68+
const { data, errors } = await fetchAllKeyTables(storedJWT);
69+
dispatch(setKeyTablesData(data));
70+
dispatch(setKeyTablesErrors(errors));
71+
if (Object.keys(errors).length > 0) {
72+
message.error(
73+
"Einige Schlüsseltabellen konnten nicht geladen werden"
74+
);
75+
}
76+
} catch (error) {
77+
console.error("Failed to fetch key tables:", error);
78+
message.error("Fehler beim Laden der Schlüsseltabellen");
79+
} finally {
80+
dispatch(setKeyTablesLoading(false));
81+
}
82+
};
83+
fetchData();
84+
}, [storedJWT, keyTablesFetched, dispatch]);
4585
const [windowWidth, windowHeight] = useWindowSize();
4686
const { routedMapRef } = useContext<typeof TopicMapContext>(TopicMapContext);
4787

@@ -56,7 +96,7 @@ const MainPage = () => {
5696
};
5797

5898
return (
59-
<>
99+
<Spin spinning={keyTablesLoading || featureLoading}>
60100
<div className="mx-3 mt-1">
61101
<CustomCard
62102
title={isDatasheetOpen ? "Datenblatt" : "Karte"}
@@ -132,7 +172,7 @@ const MainPage = () => {
132172
<BelisMapLibWrapper mapSizes={mapStyle} />
133173
</CustomCard>
134174
</div>
135-
</>
175+
</Spin>
136176
);
137177
};
138178

apps/belis/desktop/src/components/ui/BelisDatasheetView.tsx

Lines changed: 46 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,20 @@
77
*/
88

99
import { getVCard } from "@carma-appframeworks/belis";
10+
import { FeaturesFormsWrapper } from "./featuresForm";
1011

1112
interface BelisDatasheetViewProps {
1213
feature: any | null;
1314
rawFeature: any | null;
15+
fetchedData?: any | null;
16+
featureType?: string;
1417
}
1518

1619
const BelisDatasheetView = ({
1720
feature,
1821
rawFeature,
22+
fetchedData,
23+
featureType,
1924
}: BelisDatasheetViewProps) => {
2025
if (!feature && !rawFeature) {
2126
return (
@@ -48,60 +53,48 @@ const BelisDatasheetView = ({
4853
const props = rawFeature?.properties ?? feature?.properties ?? {};
4954

5055
return (
51-
<div style={{ height: "100%", overflow: "auto", padding: 16 }}>
52-
{/* Header */}
53-
<div
54-
style={{
55-
marginBottom: 16,
56-
paddingBottom: 12,
57-
borderBottom: "1px solid #ddd",
58-
}}
59-
>
60-
{infobox?.header && (
61-
<div style={{ fontSize: 11, color: "#666", marginBottom: 2 }}>
62-
{infobox.header}
63-
</div>
64-
)}
65-
<div style={{ fontSize: 16, fontWeight: 600 }}>
66-
{infobox?.title ?? rawFeature?.id ?? "Objekt"}
67-
</div>
68-
{infobox?.subtitle && (
69-
<div style={{ fontSize: 13, color: "#555", marginTop: 2 }}>
70-
{infobox.subtitle}
71-
</div>
72-
)}
73-
</div>
56+
<div style={{ height: "100%", padding: "10px 4px 8px 16px" }}>
57+
{/* Fetched feature data - render form or JSON fallback */}
58+
{fetchedData && (
59+
<FeaturesFormsWrapper
60+
featureType={featureType}
61+
data={fetchedData}
62+
rawFeature={rawFeature}
63+
/>
64+
)}
7465

75-
{/* Feature data placeholder */}
76-
<div>
77-
<div
78-
style={{
79-
fontSize: 12,
80-
fontWeight: 600,
81-
color: "#888",
82-
marginBottom: 8,
83-
textTransform: "uppercase",
84-
letterSpacing: "0.05em",
85-
}}
86-
>
87-
Feature-Daten (Vorschau)
88-
</div>
89-
<pre
90-
style={{
91-
fontSize: 11,
92-
lineHeight: 1.5,
93-
background: "#f5f5f5",
94-
padding: 12,
95-
borderRadius: 4,
96-
overflow: "auto",
97-
maxHeight: 600,
98-
whiteSpace: "pre-wrap",
99-
wordBreak: "break-word",
100-
}}
101-
>
102-
{JSON.stringify(props, null, 2)}
103-
</pre>
104-
</div>
66+
{/* Feature data placeholder (original - hidden when fetchedData available) */}
67+
{/* {!fetchedData && (
68+
<div>
69+
<div
70+
style={{
71+
fontSize: 12,
72+
fontWeight: 600,
73+
color: "#888",
74+
marginBottom: 8,
75+
textTransform: "uppercase",
76+
letterSpacing: "0.05em",
77+
}}
78+
>
79+
Feature-Daten (Vorschau)
80+
</div>
81+
<pre
82+
style={{
83+
fontSize: 11,
84+
lineHeight: 1.5,
85+
background: "#f5f5f5",
86+
padding: 12,
87+
borderRadius: 4,
88+
overflow: "auto",
89+
maxHeight: 600,
90+
whiteSpace: "pre-wrap",
91+
wordBreak: "break-word",
92+
}}
93+
>
94+
{JSON.stringify(props, null, 2)}
95+
</pre>
96+
</div> */}
97+
{/* )} */}
10598
</div>
10699
);
107100
};

0 commit comments

Comments
 (0)