Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
d0c258d
fix: [BATOOLW-179] update data forest_types_sz
ElkeErhardt Jan 13, 2026
bb49586
[BATOOLW-194] update forest types fr woth altitudinal zone
ElkeErhardt Jan 20, 2026
7f837dc
fix(VD): add VD projections
danji90 Nov 6, 2025
2eeaee1
chore: clean
danji90 Nov 6, 2025
08ccd49
[BATOOLW-189] change additional Info to projections
ElkeErhardt Dec 1, 2025
6f8ad54
chore: fix typo
danji90 Dec 4, 2025
d465b5a
fix: select first item for additional field
friedjoff Dec 8, 2025
121d0e1
fix: activate first item for relief field if non selected
friedjoff Dec 8, 2025
d505f48
fix: use "unknown" as default value for secondary fields.
friedjoff Dec 17, 2025
df53a60
chore: add vd tree data, update import script
danji90 Nov 12, 2025
f89db28
chore: use new tables in TreeClient
danji90 Nov 20, 2025
2a2001e
chore: clean
danji90 Nov 20, 2025
99aef73
chore: rebase master
danji90 Feb 11, 2026
5db3c43
fix(treetypes): remove Paulownia tree type (#751)
danji90 Feb 11, 2026
1b11e5a
fix(PWA): fix offline mode (#734)
friedjoff Feb 11, 2026
d92e4be
fix(vd): update vd forest types (#752)
danji90 Feb 12, 2026
efa4af9
Merge branch 'master' into staging
danji90 Feb 19, 2026
83f1de6
chore: create all VD types tables
danji90 Mar 2, 2026
80f122e
Merge branch 'production'
danji90 Mar 2, 2026
85cdb91
fix: update FR sql fields, add output log in data:start script
danji90 Mar 4, 2026
972a6f5
Merge branch 'master' into update_forest_types_sz
danji90 Mar 5, 2026
e466b27
chore: merge FR updates
danji90 Mar 5, 2026
d7b476c
chore: comment out SZ import
danji90 Mar 5, 2026
186cf3e
Merge branch 'master' into daniel/updateFrTiles
danji90 Mar 5, 2026
fd08fea
chore: merge FR updates
danji90 Mar 5, 2026
c2f4c3a
chore: update sqlite
danji90 Mar 5, 2026
6b5fabd
chore: reinsert vd tables in sqlite db
danji90 Mar 5, 2026
530400f
chore: reinsert vd tables
danji90 Mar 5, 2026
9984aa7
chore: remove Paulownia tree from tree types
danji90 Mar 9, 2026
8fcaa4e
Merge branch 'master' into daniel/addVdSpecificData
danji90 Mar 9, 2026
b7c7b37
chore: merge master
danji90 Mar 9, 2026
4f45189
chore: fix pnpm-lock
danji90 Mar 9, 2026
fe6ee1d
Merge branch 'master' into daniel/addVdSpecificData
danji90 Mar 9, 2026
5fc0610
chore: update VD CSVs, rebuild DB
danji90 Mar 9, 2026
db33daf
chore: update and correct CSV data, update db
danji90 Mar 9, 2026
0c74345
chore: update db
danji90 Mar 9, 2026
95e746a
chore: merge VD updates
danji90 Mar 9, 2026
d70dd35
Merge branch 'master' into staging
danji90 Mar 10, 2026
a00278a
Merge branch 'master' into daniel/addVdSpecificData
danji90 May 27, 2026
7edd767
Merge branch 'master' into staging
danji90 May 27, 2026
e5813d2
chore: remove all VD specific treetype data and code
danji90 May 28, 2026
80e6c86
chore: update maps.geo.admin import urls, adjust some scripts
danji90 May 28, 2026
a4a6307
chore: merge VD stuff
danji90 May 28, 2026
68dfa9b
chore: clean
danji90 May 28, 2026
cab11b4
Merge branch 'daniel/addVdSpecificData' into staging
danji90 May 28, 2026
124aa36
fix(tg): add new attributes to table, add az values az export view
danji90 Jun 22, 2026
ab6c190
Merge branch 'daniel/addVdSpecificData' into daniel/tgDataUpdateWithVD
danji90 Jun 25, 2026
0bafa92
chore: upfate import data script to support forest_type gpkg files
danji90 Jun 29, 2026
73a17cc
chore: fix hono server
danji90 Jun 29, 2026
dc1556f
merge master, update documentation
danji90 Jun 29, 2026
c33c556
chore: simply field options fetch, update local tile server script
danji90 Jun 29, 2026
50e7cf2
chore: merge master
danji90 Jun 29, 2026
5110286
Merge branch 'daniel/tgDataUpdateWithVD' into staging
danji90 Jun 29, 2026
103a4f6
fix: redirect to /projection by default, dix minor location form issues
danji90 Jun 29, 2026
5d3cb42
fix(location): always switch to f projection form from location ft bu…
danji90 Jun 29, 2026
4fa0be4
fix(tg): add new attributes to table, add az values az export view
danji90 Jun 22, 2026
3ee5e2c
chore: create all VD types tables
danji90 Mar 2, 2026
7f16773
chore: update VD CSVs, rebuild DB
danji90 Mar 9, 2026
cae02a6
chore: update and correct CSV data, update db
danji90 Mar 9, 2026
45948e9
chore: remove all VD specific treetype data and code
danji90 May 28, 2026
8b640ed
chore: update maps.geo.admin import urls, adjust some scripts
danji90 May 28, 2026
5aaaf89
chore: clean
danji90 May 28, 2026
faf9005
chore: upfate import data script to support forest_type gpkg files
danji90 Jun 29, 2026
259ec10
chore: fix hono server
danji90 Jun 29, 2026
e276e48
chore: simply field options fetch, update local tile server script
danji90 Jun 29, 2026
670ab7f
fix: redirect to /projection by default, dix minor location form issues
danji90 Jun 29, 2026
bdc47a1
fix(location): always switch to f projection form from location ft bu…
danji90 Jun 29, 2026
fa2ef3f
Merge branch 'daniel/tgDataUpdateWithVD' of github.com:geops/tree-app…
danji90 Jun 29, 2026
65c4bcb
chore: clean merge
danji90 Jun 29, 2026
61339a7
chore: create all VD types tables
danji90 Mar 2, 2026
4d4cb19
chore: update VD CSVs, rebuild DB
danji90 Mar 9, 2026
5cb2855
chore: update and correct CSV data, update db
danji90 Mar 9, 2026
f5f5ec4
chore: remove all VD specific treetype data and code
danji90 May 28, 2026
f627aa0
chore: update maps.geo.admin import urls, adjust some scripts
danji90 May 28, 2026
ef575fa
chore: upfate import data script to support forest_type gpkg files
danji90 Jun 29, 2026
62f0780
Merge branch 'daniel/tgDataUpdateWithVD' of github.com:geops/tree-app…
danji90 Jun 29, 2026
6112693
Merge branch 'daniel/tgDataUpdateWithVD' into staging
danji90 Jun 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ lib/data/spatial/forest_types_tg
lib/data/spatial/forest_types_vd
lib/data/spatial/forest_types_zh
lib/data/spatial/forest_types_zh_2
lib/data/spatial/forest_types_union
lib/data/spatial/silver_fir_areas
lib/data/spatial/cantonal_boundaries.zip
lib/data/spatial/*.zip
Expand Down
29 changes: 11 additions & 18 deletions components/ForestEcoregionField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useTranslation } from "react-i18next";

import { TreeAppLanguage } from "@/i18n/i18next";
import useStore from "@/store";
import { getTypeOptions } from "@/utils/getTypeOptions";

import Dropdown, { DropdownOption } from "./ui/Dropdown";
import Input from "./ui/Input";
Expand All @@ -26,24 +27,16 @@ function ForestEcoregionField() {

const options = useMemo(() => {
if (projectionMode === "m") return [];
const forestEcoregions = treeClient.getTypes<ForestEcoregion>(
"forestecoregion",
["code", i18n.language],
opts?.forestEcoregion?.length
? {
code: `IN (${opts.forestEcoregion.map((ecoRegion) => `'${ecoRegion}'`).join(", ")})`,
}
: undefined,
);

return (
forestEcoregions
.filter((ecoRegion) => opts.forestEcoregion?.includes(ecoRegion.code))
.map((ecoRegion) => ({
label: ecoRegion[i18n.language as TreeAppLanguage],
value: ecoRegion.code,
})) ?? []
);
return getTypeOptions<ForestEcoregion, DropdownOption>({
codes: opts?.forestEcoregion ?? [],
columns: ["code", i18n.language],
mapOption: (ecoRegion) => ({
label: ecoRegion[i18n.language as TreeAppLanguage],
value: ecoRegion.code,
}),
treeClient,
type: "forestecoregion",
});
}, [opts?.forestEcoregion, i18n.language, treeClient, projectionMode]);

if (projectionMode === "m") {
Expand Down
31 changes: 13 additions & 18 deletions components/LocationForm/IndicatorField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useTranslation } from "react-i18next";

import { TreeAppLanguage } from "@/i18n/i18next";
import useStore from "@/store";
import { getTypeOptions } from "@/utils/getTypeOptions";

import LatinSwitcher from "../LatinSwitcher";
import Dropdown from "../ui/Dropdown";
Expand All @@ -20,24 +21,18 @@ function IndicatorField() {
const latinActive = useStore((state) => state.latinActive);

const options = useMemo(() => {
if (!opts?.indicator?.length) return [];
const indicators = treeClient.getTypes<TranslatedTypeRecordLatin>(
"indicator",
["code", "la", i18n.language],
opts?.indicator?.length
? { code: `IN (${opts.indicator.map((ind) => `${ind}`).join(", ")})` }
: undefined,
);

return (
indicators
.filter((ind) => opts.indicator?.includes(ind.code))
.map((ind) => ({
filterValue: `${ind.la} ${ind[i18n.language as TreeAppLanguage]}`,
label: latinActive ? ind.la : ind[i18n.language as TreeAppLanguage],
value: ind.code,
})) ?? []
);
return getTypeOptions<TranslatedTypeRecordLatin, DropdownOption>({
codes: opts?.indicator ?? [],
columns: ["code", "la", i18n.language],
mapOption: (ind) => ({
filterValue: `${ind.la} ${ind[i18n.language as TreeAppLanguage]}`,
label: latinActive ? ind.la : ind[i18n.language as TreeAppLanguage],
value: ind.code,
}),
quoteCodes: false,
treeClient,
type: "indicator",
});
}, [opts?.indicator, i18n.language, treeClient, latinActive]);

return (
Expand Down
29 changes: 11 additions & 18 deletions components/LocationForm/SilverFirAreaField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useTranslation } from "react-i18next";

import { TreeAppLanguage } from "@/i18n/i18next";
import useStore from "@/store";
import { getTypeOptions } from "@/utils/getTypeOptions";

import Dropdown from "../ui/Dropdown";
import Input from "../ui/Input";
Expand All @@ -23,24 +24,16 @@ function SilverFirAreaField() {

const options = useMemo(() => {
if (projectionMode === "m" || !opts?.silverFirArea?.length) return [];
const silverFirAreas = treeClient.getTypes<SilverFirArea>(
"silverfirarea",
["code", i18n.language],
opts?.silverFirArea?.length
? {
code: `IN (${opts.silverFirArea.map((sfa) => `'${sfa}'`).join(", ")})`,
}
: undefined,
);

return (
silverFirAreas
.filter((sfa) => opts.silverFirArea?.includes(sfa.code))
.map((sfa) => ({
label: sfa[i18n.language as TreeAppLanguage],
value: sfa.code,
})) ?? []
);
return getTypeOptions<SilverFirArea, DropdownOption>({
codes: opts.silverFirArea,
columns: ["code", i18n.language],
mapOption: (sfa) => ({
label: sfa[i18n.language as TreeAppLanguage],
value: sfa.code,
}),
treeClient,
type: "silverfirarea",
});
}, [opts?.silverFirArea, i18n.language, treeClient, projectionMode]);

if (projectionMode === "m") {
Expand Down
30 changes: 12 additions & 18 deletions components/LocationForm/TreeTypesField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useTranslation } from "react-i18next";

import { TreeAppLanguage } from "@/i18n/i18next";
import useStore from "@/store";
import { getTypeOptions } from "@/utils/getTypeOptions";

import LatinSwitcher from "../LatinSwitcher";
import Dropdown from "../ui/Dropdown";
Expand All @@ -20,24 +21,17 @@ function TreeTypesField() {
const latinActive = useStore((state) => state.latinActive);

const options = useMemo(() => {
if (!opts?.treeType?.length) return [];
const treeTypes = treeClient.getTypes<TranslatedTypeRecordLatin>(
"treetype",
["code", "la", i18n.language],
opts?.treeType?.length
? { code: `IN (${opts.treeType.map((tt) => `'${tt}'`).join(", ")})` }
: undefined,
);

return (
treeTypes
.filter((tt) => opts.treeType?.includes(tt.code))
.map((tt) => ({
filterValue: `${tt.la} ${tt[i18n.language as TreeAppLanguage]}`,
label: latinActive ? tt.la : tt[i18n.language as TreeAppLanguage],
value: tt.code,
})) ?? []
);
return getTypeOptions<TranslatedTypeRecordLatin, DropdownOption>({
codes: opts?.treeType ?? [],
columns: ["code", "la", i18n.language],
mapOption: (tt) => ({
filterValue: `${tt.la} ${tt[i18n.language as TreeAppLanguage]}`,
label: latinActive ? tt.la : tt[i18n.language as TreeAppLanguage],
value: tt.code,
}),
treeClient,
type: "treetype",
});
}, [opts, i18n.language, treeClient, latinActive]);

return (
Expand Down
15 changes: 8 additions & 7 deletions components/LocationForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ function LocationForm() {
const { t } = useTranslation();
const formLocation = useStore((state) => state.formLocation);
const setFormLocation = useStore((state) => state.setFormLocation);
const hasFilters =
intersection(
Object.keys(formLocation).filter(
(key): key is keyof Location => !!formLocation[key as keyof Location],
),
filterFields,
)?.length > 0;

return (
<div className="flex flex-col gap-4 px-5">
Expand Down Expand Up @@ -87,13 +94,7 @@ function LocationForm() {
},
]}
/>
{intersection(
Object.keys(formLocation).filter(
(key): key is keyof Location =>
formLocation[key as keyof Location] !== "",
),
filterFields,
)?.length > 0 && (
{hasFilters && (
<Button
className="my-4"
onClick={() => {
Expand Down
14 changes: 5 additions & 9 deletions components/LocationResult/EcogramPopup.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { useRouter } from "next/router";
import { useMemo, useRef } from "react";
import { useTranslation } from "react-i18next";
import { Tooltip, TooltipRefProps } from "react-tooltip";
Expand All @@ -8,19 +7,19 @@ import useStore from "@/store";
import Button from "../ui/Button";
import InfoButton from "../ui/InfoButton";

import ForestTypeButton from "./ForestTypeButton";

import type { ForestType } from "@geops/tree-lib/types";

import type { TreeAppLanguage } from "@/i18n/i18next";

function EcogramPopup({ forestTypes }: { forestTypes: string[] }) {
const { i18n, t } = useTranslation();
const router = useRouter();
const activeProfile = useStore((state) => state.activeProfile);
const treeClient = useStore((state) => state.treeClient);
const setForestTypeDescription = useStore(
(state) => state.setForestTypeDescription,
);
const setFormLocation = useStore((state) => state.setFormLocation);
const refTooltip = useRef<TooltipRefProps>(null);

const forestTypeInfos: ForestType[] = useMemo(() => {
Expand Down Expand Up @@ -74,16 +73,13 @@ function EcogramPopup({ forestTypes }: { forestTypes: string[] }) {
className="h-12 w-12 min-w-12 rounded bg-primary-500 text-white hover:bg-primary-200 hover:text-white"
onClick={() => setForestTypeDescription(code)}
/>
<Button
<ForestTypeButton
className="truncate"
onClick={() => {
setFormLocation({ forestType: code });
void router.push(`/projection${window.location.search}`);
}}
code={code}
title={`${code} - ${name}`}
>
{code} - {name}
</Button>
</ForestTypeButton>
</li>
);
})}
Expand Down
35 changes: 35 additions & 0 deletions components/LocationResult/ForestTypeButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { useRouter } from "next/router";

import useStore from "@/store";

import Button, { ButtonProps } from "../ui/Button";

interface ForestTypeButtonProps extends ButtonProps {
code: string;
}

export default function ForestTypeButton({
children,
className,
code,
disabled,
...props
}: ForestTypeButtonProps) {
const setFormLocation = useStore((state) => state.setFormLocation);
const setProjectionMode = useStore((state) => state.setProjectionMode);
const router = useRouter();
return (
<Button
className={className}
disabled={disabled}
onClick={() => {
setProjectionMode("f");
setFormLocation({ forestType: code });
void router.push(`/projection${window.location.search}`);
}}
{...props}
>
{children}
</Button>
);
}
37 changes: 22 additions & 15 deletions components/LocationResult/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { useRouter } from "next/router";
import { useTranslation } from "react-i18next";

import useStore from "@/store";

import Button from "../ui/Button";
import Message from "../ui/Message";
import InfoModal from "../ui/Modal";

import Ecogram from "./Ecogram";
import ForestTypeButton from "./ForestTypeButton";

import type { ForestType, TreeLocationGroup } from "@geops/tree-lib/types";

Expand All @@ -22,16 +21,26 @@ const otherForestTypeGroups: TreeLocationGroup[] = [

function LocationResult() {
const { i18n, t } = useTranslation();
const router = useRouter();
const location = useStore((state) => state.location);
const formLocation = useStore((state) => state.formLocation);
const projectionMode = useStore((state) => state.projectionMode);
const treeClient = useStore((state) => state.treeClient);
const setFormLocation = useStore((state) => state.setFormLocation);
const { ecogram, forestTypes } = useStore((state) => state.locationResult);
console.log(formLocation);

const hasMainGroup =
!formLocation.groups || formLocation.groups.includes("main");
!formLocation.groups || formLocation.groups?.includes("main");
const hasOtherGroup =
!formLocation.groups ||
formLocation.groups.filter((group) => group !== "main").length > 0;
formLocation.groups.every((group) => group !== "main");
const hasRequiredFields =
projectionMode === "m"
? !!(location.altitudinalZone && location.forestEcoregion)
: !!(formLocation.altitudinalZone && formLocation.forestEcoregion);
const requirementsMessage =
projectionMode === "m"
? "projection.missingLocation"
: "location.selectAzAndEcoregion";

return forestTypes ? (
<div className="px-5">
Expand Down Expand Up @@ -61,6 +70,9 @@ function LocationResult() {
{t("location.otherResultHelp")}
</InfoModal>
</div>
{!hasRequiredFields && (
<Message className="mb-2">{t(requirementsMessage)}</Message>
)}
<div className="flex flex-col gap-4">
{otherForestTypeGroups
.filter((group) => forestTypes[group].length > 0)
Expand All @@ -73,24 +85,19 @@ function LocationResult() {
ftCode,
["code", i18n.language as TreeAppLanguage],
);
const onClick = () => {
setFormLocation({ forestType: ftCode });
void router.push(
`/projection${window.location.search}`,
);
};
return (
<li key={ftCode}>
<Button
<ForestTypeButton
className="grid grid-cols-[auto,auto,auto] gap-2 text-left"
onClick={onClick}
code={ftCode}
disabled={!hasRequiredFields}
>
<div>{ftCode}</div>
<div>-</div>
<div>
{ftInfo?.[i18n.language as TreeAppLanguage]}
</div>
</Button>
</ForestTypeButton>
</li>
);
})}
Expand Down
Loading