Skip to content

Commit 5df8be4

Browse files
committed
CMS: Report collection
1 parent 9720155 commit 5df8be4

16 files changed

Lines changed: 319 additions & 64 deletions

File tree

client/src/app/(frontend)/parsers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { z } from "zod";
1111
import { ContextDescriptionType } from "@/types/generated/api.schemas";
1212
import { VisualizationTypes } from "@/types/indicator";
1313

14-
import { BasemapIds } from "@/components/map/controls/basemap";
14+
import { BasemapIds } from "@/constants/basemaps";
1515

1616
type IndicatorViewBase = {
1717
id: number;

client/src/app/(payload)/admin/importMap.js

Lines changed: 49 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

client/src/app/(payload)/api/[...slug]/route.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
22
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
3-
import config from "@payload-config";
4-
5-
import "@payloadcms/next/css";
63
import {
74
REST_DELETE,
85
REST_GET,
@@ -12,6 +9,10 @@ import {
129
REST_PUT,
1310
} from "@payloadcms/next/routes";
1411

12+
import config from "@payload-config";
13+
14+
import "@payloadcms/next/css";
15+
1516
export const GET = REST_GET(config);
1617
export const POST = REST_POST(config);
1718
export const DELETE = REST_DELETE(config);
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
22
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
3+
import { GRAPHQL_PLAYGROUND_GET } from "@payloadcms/next/routes";
4+
35
import config from "@payload-config";
46

57
import "@payloadcms/next/css";
6-
import { GRAPHQL_PLAYGROUND_GET } from "@payloadcms/next/routes";
78

89
export const GET = GRAPHQL_PLAYGROUND_GET(config);
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import type { CollectionConfig } from "payload";
2+
3+
import { LocationField } from "@/cms/fields/location";
4+
import { TopicsField } from "@/cms/fields/topics";
5+
6+
export const Reports: CollectionConfig = {
7+
slug: "reports",
8+
fields: [
9+
{
10+
name: "title",
11+
type: "text",
12+
},
13+
{
14+
name: "description",
15+
type: "richText",
16+
},
17+
18+
LocationField,
19+
TopicsField,
20+
],
21+
};

client/src/cms/fields/location.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { Field } from "payload";
2+
3+
export const LocationField: Field = {
4+
name: "location",
5+
label: "Location",
6+
type: "json",
7+
required: true,
8+
admin: {
9+
description: "The location of the feature, represented as a GeoJSON object.",
10+
},
11+
jsonSchema: {
12+
// The way the following two properties are defined is required to indicate that we will use a local schema
13+
uri: "a://b/location.json", // required
14+
fileMatch: ["a://b/location.json"], // required
15+
schema: {
16+
type: "object",
17+
oneOf: [
18+
{
19+
type: "object",
20+
properties: {
21+
type: {
22+
type: "string",
23+
const: "search",
24+
},
25+
key: {
26+
oneOf: [{ type: "string" }, { type: "number" }],
27+
},
28+
text: {
29+
type: "string",
30+
},
31+
sourceIndex: {
32+
type: "number",
33+
},
34+
},
35+
required: ["type", "key", "text", "sourceIndex"],
36+
additionalProperties: false,
37+
},
38+
{
39+
type: "object",
40+
properties: {
41+
type: {
42+
type: "string",
43+
enum: ["point", "multipoint", "polyline", "polygon", "multipatch", "extent"],
44+
},
45+
geometry: {
46+
type: "object",
47+
additionalProperties: true,
48+
},
49+
buffer: {
50+
type: "number",
51+
},
52+
},
53+
required: ["type", "geometry", "buffer"],
54+
additionalProperties: false,
55+
},
56+
],
57+
},
58+
},
59+
};

client/src/cms/fields/topics.ts

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import { Field } from "payload";
2+
3+
import { BASEMAPS } from "@/constants/basemaps";
4+
5+
export const TopicsField: Field = {
6+
name: "topics",
7+
type: "array",
8+
fields: [
9+
{
10+
name: "topic_id",
11+
type: "number",
12+
unique: true,
13+
},
14+
{
15+
name: "description",
16+
type: "richText",
17+
},
18+
{
19+
name: "indicators",
20+
type: "array",
21+
fields: [
22+
{
23+
name: "indicator_id",
24+
type: "number",
25+
unique: true,
26+
},
27+
{
28+
name: "type",
29+
type: "radio",
30+
options: [
31+
{
32+
label: "Map",
33+
value: "map",
34+
},
35+
{
36+
label: "Chart",
37+
value: "chart",
38+
},
39+
{
40+
label: "Table",
41+
value: "table",
42+
},
43+
{
44+
label: "Numeric",
45+
value: "numeric",
46+
},
47+
{
48+
label: "Custom",
49+
value: "custom",
50+
},
51+
],
52+
},
53+
{
54+
name: "x",
55+
label: "X Coordinate",
56+
type: "number",
57+
},
58+
{
59+
name: "y",
60+
label: "Y Coordinate",
61+
type: "number",
62+
},
63+
{
64+
name: "w",
65+
label: "Width",
66+
type: "number",
67+
},
68+
{
69+
name: "h",
70+
label: "Height",
71+
type: "number",
72+
},
73+
{
74+
name: "basemapId",
75+
type: "radio",
76+
required: false,
77+
options: BASEMAPS.map((basemap) => ({
78+
label: basemap.id,
79+
value: basemap.id,
80+
})),
81+
defaultValue: "gray-vector",
82+
admin: {
83+
condition: (_, siblingData) => {
84+
return siblingData.type === "map";
85+
},
86+
},
87+
hooks: {
88+
beforeChange: [
89+
({ value, siblingData }) => {
90+
if (siblingData.type !== "map") return null;
91+
92+
return value;
93+
},
94+
],
95+
},
96+
},
97+
{
98+
name: "opacity",
99+
type: "number",
100+
required: false,
101+
defaultValue: 1,
102+
admin: {
103+
condition: (_, siblingData) => {
104+
return siblingData.type === "map";
105+
},
106+
},
107+
hooks: {
108+
beforeChange: [
109+
({ value, siblingData }) => {
110+
if (siblingData.type !== "map") return null;
111+
112+
return value;
113+
},
114+
],
115+
},
116+
},
117+
],
118+
},
119+
],
120+
};

client/src/components/map/controls/basemap.tsx

Lines changed: 13 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import { LuLayers } from "react-icons/lu";
1212

1313
import { cn } from "@/lib/utils";
1414

15+
import { BasemapIds, BASEMAPS } from "@/constants/basemaps";
16+
1517
import { useMap } from "@/components/map/provider";
1618
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
1719
import { Tooltip, TooltipArrow, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
@@ -23,50 +25,6 @@ export interface BasemapControlProps {
2325
onBasemapChange?: (selectedBasemapId: BasemapIds) => void;
2426
}
2527

26-
export const BASEMAPS = [
27-
{
28-
id: "gray-vector",
29-
label: "basemap-gray",
30-
basemap: Basemap.fromId("gray-vector"),
31-
},
32-
{
33-
id: "dark-gray-vector",
34-
label: "basemap-dark-gray",
35-
basemap: Basemap.fromId("dark-gray-vector"),
36-
},
37-
{
38-
id: "satellite",
39-
label: "basemap-satellite",
40-
basemap: Basemap.fromId("satellite"),
41-
},
42-
{
43-
id: "streets",
44-
label: "basemap-streets",
45-
basemap: Basemap.fromId("streets"),
46-
},
47-
{
48-
id: "hybrid",
49-
label: "basemap-hybrid",
50-
basemap: Basemap.fromId("hybrid"),
51-
},
52-
{
53-
id: "osm",
54-
label: "basemap-osm",
55-
basemap: Basemap.fromId("osm"),
56-
},
57-
{
58-
id: "topo-vector",
59-
label: "basemap-topographic",
60-
basemap: Basemap.fromId("topo-vector"),
61-
},
62-
{
63-
id: "terrain",
64-
label: "basemap-terrain",
65-
basemap: Basemap.fromId("terrain"),
66-
},
67-
] as const;
68-
export type BasemapIds = (typeof BASEMAPS)[number]["id"];
69-
7028
export const BasemapControl: FC<BasemapControlProps> = ({
7129
className,
7230
onBasemapChange,
@@ -84,6 +42,13 @@ export const BasemapControl: FC<BasemapControlProps> = ({
8442
[mapContext, onBasemapChange],
8543
);
8644

45+
const BS = useMemo(() => {
46+
return BASEMAPS.map((b) => ({
47+
...b,
48+
basemap: Basemap.fromId(b.id),
49+
}));
50+
}, []);
51+
8752
const activeBasemapId = useMemo(() => mapContext?.map?.basemap?.id, [mapContext?.map?.basemap]);
8853

8954
return (
@@ -108,12 +73,14 @@ export const BasemapControl: FC<BasemapControlProps> = ({
10873

10974
<PopoverContent side="left" align="start" className="w-auto bg-background p-0">
11075
<ul className="flex flex-col">
111-
{BASEMAPS.map((b) => {
76+
{BS.map((b) => {
11277
return (
11378
<li key={b.id} className="flex">
11479
<button
11580
className={cn({
116-
"group flex w-full items-center space-x-2 p-2 transition-colors duration-200 hover:bg-muted": true,
81+
"group flex w-full items-center space-x-2 p-2 transition-colors duration-200 hover:bg-muted":
82+
//
83+
true,
11784
"bg-foreground hover:bg-foreground": activeBasemapId === b.id,
11885
})}
11986
type="button"

client/src/components/map/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ import { merge } from "ts-deepmerge";
1616

1717
import { omit } from "@/lib/utils";
1818

19+
import { BasemapIds } from "@/constants/basemaps";
1920
import { DEFAULT_MAP_VIEW_PROPERTIES } from "@/constants/map";
2021

21-
import { BasemapIds } from "@/components/map/controls/basemap";
2222
import { LayerView, MapContext, MapProvider } from "@/components/map/provider";
2323

2424
export type MapProps = {

0 commit comments

Comments
 (0)