Skip to content

Commit dcf361d

Browse files
committed
c'est compliqué :/
1 parent ceaaf97 commit dcf361d

File tree

5 files changed

+152
-52
lines changed

5 files changed

+152
-52
lines changed

assets/components/Utils/Geostyler/UploadStyleFile.tsx

Lines changed: 95 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { fr } from "@codegouvfr/react-dsfr";
2+
import Accordion from "@codegouvfr/react-dsfr/Accordion";
23
import Alert from "@codegouvfr/react-dsfr/Alert";
34
import Button from "@codegouvfr/react-dsfr/Button";
45
import { Upload } from "@codegouvfr/react-dsfr/Upload";
@@ -12,8 +13,8 @@ import { StyleFormatEnum } from "@/@types/app";
1213
import { useStyleForm } from "@/contexts/StyleFormContext";
1314
import { useTranslation } from "@/i18n";
1415
import TMSStyleTools from "@/modules/Style/TMSStyleFilesManager/TMSStyleTools";
15-
import { encodeKey, getFileExtension } from "@/utils";
16-
import { getParserForExtension, mbParser, sldParser } from "@/utils/geostyler";
16+
import { encodeKey, getFileExtension, readFileContent } from "@/utils";
17+
import { getDefaultStyle, getParserForExtension, mbParser, propertyNamesToLowerCase, sldParser } from "@/utils/geostyler";
1718
import ConfirmDialog, { ConfirmDialogModal } from "../ConfirmDialog";
1819
import LoadingText from "../LoadingText";
1920
import useStylesHandler from "./useStylesHandler";
@@ -29,32 +30,6 @@ type UploadStyleFileProps = {
2930
acceptedFileExtensions?: string[];
3031
};
3132

32-
function propertyNamesToLowerCase(sldContent: string) {
33-
return sldContent.replace(/<(ogc:)?PropertyName>(.*?)<\/(ogc:)?PropertyName>/g, (_, p1, p2) => {
34-
return `<${p1 ?? ""}PropertyName>${p2.toLowerCase()}</${p1 ?? ""}PropertyName>`;
35-
});
36-
}
37-
38-
function getDefaultStyle(currentTable: string): GsStyle {
39-
return {
40-
name: currentTable,
41-
rules: [
42-
{
43-
name: `rule_${Math.floor(Math.random() * 10000)
44-
.toString()
45-
.padStart(4, "0")}`,
46-
symbolizers: [
47-
{
48-
kind: "Mark",
49-
wellKnownName: "circle",
50-
color: "#0E1058",
51-
},
52-
],
53-
},
54-
],
55-
};
56-
}
57-
5833
const tmsStyleTools = new TMSStyleTools();
5934

6035
const UploadStyleFile: FC<UploadStyleFileProps> = (props) => {
@@ -63,9 +38,21 @@ const UploadStyleFile: FC<UploadStyleFileProps> = (props) => {
6338
const { t } = useTranslation("UploadStyleFile");
6439

6540
const { currentTable, styleFormats, service, isMapbox } = useStyleForm();
66-
const { setError, trigger } = useFormContext();
67-
68-
const { gsStyle, setGsStyle, strStyle } = useStylesHandler({
41+
const {
42+
formState: { errors },
43+
setError,
44+
trigger,
45+
} = useFormContext();
46+
47+
const {
48+
gsStyle,
49+
setGsStyle,
50+
strStyle,
51+
readStyleResult,
52+
setReadStyleResult,
53+
writeStyleResult,
54+
// setWriteStyleResult
55+
} = useStylesHandler({
6956
parser,
7057
format: styleFormats[currentTable] ?? StyleFormatEnum.SLD,
7158
initialStrStyle: value,
@@ -97,22 +84,6 @@ const UploadStyleFile: FC<UploadStyleFileProps> = (props) => {
9784
}
9885
}, [strStyle, encodedFieldName]);
9986

100-
const readFileContent = async (file: File): Promise<string> => {
101-
return new Promise((resolve, reject) => {
102-
const reader = new FileReader();
103-
reader.onerror = () => reject(new Error("Impossible de lire le fichier sélectionné"));
104-
reader.onabort = () => reject(new Error("Lecture du fichier annulée"));
105-
reader.onload = (e) => {
106-
if (typeof e.target?.result === "string") {
107-
resolve(e.target.result);
108-
} else {
109-
reject(new Error("Format de fichier non supporté"));
110-
}
111-
};
112-
reader.readAsText(file);
113-
});
114-
};
115-
11687
async function handleUpload(event: React.ChangeEvent<HTMLInputElement>) {
11788
setUploadError(undefined);
11889

@@ -134,6 +105,7 @@ const UploadStyleFile: FC<UploadStyleFileProps> = (props) => {
134105
onFormatChange?.(targetFormat);
135106

136107
const gsStyleResult: ReadStyleResult | undefined = await parser.readStyle(extension === "json" ? JSON.parse(content) : content);
108+
setReadStyleResult(gsStyleResult);
137109

138110
// debug
139111
if (gsStyleResult.unsupportedProperties) console.warn("unsupported", gsStyleResult.unsupportedProperties);
@@ -148,6 +120,7 @@ const UploadStyleFile: FC<UploadStyleFileProps> = (props) => {
148120
try {
149121
const currentStr = strStyle;
150122
const writeRes = await parser.writeStyle(gsStyle);
123+
// setWriteStyleResult(writeRes);
151124
const newStr = typeof writeRes.output === "object" ? JSON.stringify(writeRes.output) : (writeRes.output as string);
152125

153126
// mettre à jour uniquement si le style a changé
@@ -167,16 +140,20 @@ const UploadStyleFile: FC<UploadStyleFileProps> = (props) => {
167140
let defaultStyle = getDefaultStyle(currentTable);
168141

169142
if (service && isMapbox) {
170-
const output = (await mbParser.writeStyle(defaultStyle)).output;
143+
const writeResult = await mbParser.writeStyle(defaultStyle);
144+
// setWriteStyleResult(writeResult);
145+
const output = writeResult.output;
171146
if (output) {
172147
const finalMbStyle = tmsStyleTools.buildMbStyle(service, output);
173-
defaultStyle = (await mbParser.readStyle(finalMbStyle)).output as GsStyle;
148+
const readResult = await mbParser.readStyle(finalMbStyle);
149+
defaultStyle = readResult.output as GsStyle;
150+
setReadStyleResult(readResult);
174151
}
175152
}
176153

177154
setGsStyle(defaultStyle);
178155
setUploadError(undefined);
179-
}, [currentTable, setGsStyle, isMapbox, service]);
156+
}, [currentTable, setGsStyle, setReadStyleResult, isMapbox, service]);
180157

181158
const handleRemoveStyle = () => {
182159
setGsStyle(undefined);
@@ -192,6 +169,74 @@ const UploadStyleFile: FC<UploadStyleFileProps> = (props) => {
192169
{uploadError && (
193170
<Alert severity="error" title={"Erreur de chargement de style"} description={uploadError} onClose={() => setUploadError(undefined)} />
194171
)}
172+
{errors?.["style_files"]?.[encodeKey(currentTable)]?.message && (
173+
<Alert severity="error" small description={errors?.["style_files"]?.[encodeKey(currentTable)]?.message} />
174+
)}
175+
176+
<Accordion label="Read Style Result">
177+
{readStyleResult?.errors && (
178+
<>
179+
Erreurs :
180+
<pre>
181+
<code style={{ whiteSpace: "pre" }} className={fr.cx("fr-text--sm")}>
182+
{JSON.stringify(readStyleResult?.errors, null, 4)}
183+
</code>
184+
</pre>
185+
</>
186+
)}
187+
{readStyleResult?.warnings && (
188+
<>
189+
Avertissements :
190+
<pre>
191+
<code style={{ whiteSpace: "pre" }} className={fr.cx("fr-text--sm")}>
192+
{JSON.stringify(readStyleResult?.warnings, null, 4)}
193+
</code>
194+
</pre>
195+
</>
196+
)}
197+
{readStyleResult?.unsupportedProperties && (
198+
<>
199+
Propriétés non supportées :
200+
<pre>
201+
<code style={{ whiteSpace: "pre" }} className={fr.cx("fr-text--sm")}>
202+
{JSON.stringify(readStyleResult?.unsupportedProperties, null, 4)}
203+
</code>
204+
</pre>
205+
</>
206+
)}
207+
</Accordion>
208+
<Accordion label="Write Style Result">
209+
{writeStyleResult?.errors && (
210+
<>
211+
Erreurs :
212+
<pre>
213+
<code style={{ whiteSpace: "pre" }} className={fr.cx("fr-text--sm")}>
214+
{JSON.stringify(writeStyleResult?.errors, null, 4)}
215+
</code>
216+
</pre>
217+
</>
218+
)}
219+
{writeStyleResult?.warnings && (
220+
<>
221+
Avertissements :
222+
<pre>
223+
<code style={{ whiteSpace: "pre" }} className={fr.cx("fr-text--sm")}>
224+
{JSON.stringify(writeStyleResult?.warnings, null, 4)}
225+
</code>
226+
</pre>
227+
</>
228+
)}
229+
{writeStyleResult?.unsupportedProperties && (
230+
<>
231+
Propriétés non supportées :
232+
<pre>
233+
<code style={{ whiteSpace: "pre" }} className={fr.cx("fr-text--sm")}>
234+
{JSON.stringify(writeStyleResult?.unsupportedProperties, null, 4)}
235+
</code>
236+
</pre>
237+
</>
238+
)}
239+
</Accordion>
195240
{gsStyle ? (
196241
<div>
197242
<div className={fr.cx("fr-grid-row", "fr-grid-row--right")}>

assets/components/Utils/Geostyler/useStylesHandler.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { type Style as GsStyle, StyleParser } from "geostyler-style";
1+
import { type Style as GsStyle, ReadStyleResult, StyleParser, WriteStyleResult } from "geostyler-style";
22
import { Dispatch, SetStateAction, useEffect, useRef, useState } from "react";
33

44
import { StyleFormatEnum } from "@/@types/app";
@@ -13,13 +13,20 @@ type UseStylesHandlerReturn = {
1313
gsStyle: GsStyle | undefined;
1414
setGsStyle: Dispatch<SetStateAction<GsStyle | undefined>>;
1515
strStyle?: string | undefined;
16+
readStyleResult?: ReadStyleResult | undefined;
17+
setReadStyleResult: Dispatch<SetStateAction<ReadStyleResult | undefined>>;
18+
writeStyleResult?: WriteStyleResult | undefined;
19+
setWriteStyleResult: Dispatch<SetStateAction<WriteStyleResult | undefined>>;
1620
};
1721
export default function useStylesHandler(props: UseStylesHandlerProps): UseStylesHandlerReturn {
1822
const { parser, format, initialStrStyle, setError } = props;
1923

2024
const [gsStyle, setGsStyle] = useState<GsStyle | undefined>(undefined);
2125
const [strStyle, setStrStyle] = useState<string | undefined>(undefined);
2226

27+
const [readStyleResult, setReadStyleResult] = useState<ReadStyleResult | undefined>(undefined);
28+
const [writeStyleResult, setWriteStyleResult] = useState<WriteStyleResult | undefined>(undefined);
29+
2330
const setErrorRef = useRef(setError);
2431
const lastInitStrRef = useRef<string | undefined>(undefined);
2532

@@ -47,6 +54,7 @@ export default function useStylesHandler(props: UseStylesHandlerProps): UseStyle
4754
try {
4855
const input = format === StyleFormatEnum.Mapbox ? JSON.parse(initialStrStyle) : initialStrStyle;
4956
const readResult = await parser.readStyle(input);
57+
setReadStyleResult(readResult);
5058
if (readResult.output) {
5159
setGsStyle(readResult.output as GsStyle);
5260
}
@@ -86,5 +94,9 @@ export default function useStylesHandler(props: UseStylesHandlerProps): UseStyle
8694
gsStyle,
8795
setGsStyle,
8896
strStyle,
97+
readStyleResult,
98+
setReadStyleResult,
99+
writeStyleResult,
100+
setWriteStyleResult,
89101
};
90102
}

assets/utils/file.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export async function readFileContent(file: File): Promise<string> {
2+
return new Promise((resolve, reject) => {
3+
const reader = new FileReader();
4+
reader.onerror = () => reject(new Error("Impossible de lire le fichier sélectionné"));
5+
reader.onabort = () => reject(new Error("Lecture du fichier annulée"));
6+
reader.onload = (e) => {
7+
if (typeof e.target?.result === "string") {
8+
resolve(e.target.result);
9+
} else {
10+
reject(new Error("Format de fichier non supporté"));
11+
}
12+
};
13+
reader.readAsText(file);
14+
});
15+
}

assets/utils/geostyler.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import MapboxStyleParser from "geostyler-mapbox-parser";
22
import OlStyleParser from "geostyler-openlayers-parser";
33
import QGISStyleParser from "geostyler-qgis-parser";
44
import SldStyleParser from "geostyler-sld-parser";
5-
import { StyleParser } from "geostyler-style";
5+
import { Style as GsStyle, StyleParser } from "geostyler-style";
66

77
import { CartesStyle, GeostylerStyles, StyleFormatEnum } from "@/@types/app";
88

@@ -61,3 +61,29 @@ export function getParserForExtension(extension: string | undefined): StyleParse
6161
export function getParsersForExtensions(fileExtensions: string[] = ["sld"]): StyleParser[] {
6262
return fileExtensions.map((ext) => getParserForExtension(ext));
6363
}
64+
65+
export function propertyNamesToLowerCase(sldContent: string) {
66+
return sldContent.replace(/<(ogc:)?PropertyName>(.*?)<\/(ogc:)?PropertyName>/g, (_, p1, p2) => {
67+
return `<${p1 ?? ""}PropertyName>${p2.toLowerCase()}</${p1 ?? ""}PropertyName>`;
68+
});
69+
}
70+
71+
export function getDefaultStyle(currentTable: string): GsStyle {
72+
return {
73+
name: currentTable,
74+
rules: [
75+
{
76+
name: `rule_${Math.floor(Math.random() * 10000)
77+
.toString()
78+
.padStart(4, "0")}`,
79+
symbolizers: [
80+
{
81+
kind: "Mark",
82+
wellKnownName: "circle",
83+
color: "#0E1058",
84+
},
85+
],
86+
},
87+
],
88+
};
89+
}

assets/utils/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ export * from "./user";
1010
export * from "./image";
1111
export * from "./form";
1212
export * from "./delta";
13+
export * from "./geostyler";
14+
export * from "./file";
1315

1416
// charsets
1517
export { default as charsets } from "@/data/charset_list.json";

0 commit comments

Comments
 (0)