Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
a85e7a3
Setup first draft of page for adding new field
SvenVw Apr 1, 2025
f30f2aa
Remove not needing lines
SvenVw Apr 1, 2025
3e667ce
Fix layers
SvenVw Apr 1, 2025
2036e01
Fix type
SvenVw Apr 1, 2025
aac6434
Open dialog on click
SvenVw Apr 1, 2025
ecf5533
Improve accessibility of combobox
SvenVw Apr 2, 2025
04d8a12
Enable submitting a new field
SvenVw Apr 2, 2025
e754082
Add submitting stage to button
SvenVw Apr 2, 2025
9a2821d
Fix displaying on small screen
SvenVw Apr 2, 2025
9e4dee3
Remove not needed validation
SvenVw Apr 2, 2025
f2a4124
Improve colors of layers
SvenVw Apr 2, 2025
5611acf
Improve boxes
SvenVw Apr 2, 2025
4b3169f
Improve types
SvenVw Apr 2, 2025
16508ce
Fix viewState if no fields are present
SvenVw Apr 3, 2025
f7e8b09
Remove whiteline
SvenVw Apr 3, 2025
795718b
Fix form submission handling
SvenVw Apr 3, 2025
d0c5db3
Update dependencies
SvenVw Apr 4, 2025
0ab60a3
Fix submitting geometry
SvenVw Apr 4, 2025
9e43fa5
Fixes
SvenVw Apr 4, 2025
34113b1
Add changeset
SvenVw Apr 4, 2025
7d59071
Remove duplicate useEffect
SvenVw Apr 4, 2025
19f75c8
Fix submitting new field
SvenVw Apr 7, 2025
4de2785
Fixes
SvenVw Apr 7, 2025
d693cdb
Fix that soil data without sampling date is not excluded
SvenVw Apr 7, 2025
fbdf30c
Merge branch 'development' into add-field
SvenVw Apr 7, 2025
61a5157
fix lock file
SvenVw Apr 7, 2025
2ab7ffd
Various fixes due to merge with development
SvenVw Apr 7, 2025
faa950f
Fix imports
SvenVw Apr 7, 2025
98d8500
Remove duplicate code
SvenVw Apr 7, 2025
8928e95
Extend type
SvenVw Apr 7, 2025
3633d37
Add simple validation for nmi api response
SvenVw Apr 7, 2025
7019fa1
Merge branch 'development' into add-field
SvenVw Apr 10, 2025
829cd12
Match full return type
SvenVw Apr 10, 2025
c42f54b
Improve error handling
SvenVw Apr 10, 2025
a131122
Fix lockfile
SvenVw Apr 10, 2025
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
5 changes: 5 additions & 0 deletions .changeset/neat-lands-stay.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@svenvw/fdm-app": minor
---

Add page to add a field to a farm
5 changes: 5 additions & 0 deletions .changeset/slick-buses-bow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@svenvw/fdm-core": patch
---

Fix that soil data without sampling date is not excluded
9 changes: 4 additions & 5 deletions fdm-app/app/components/custom/atlas/atlas-sources.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ export function FieldsSourceSelected({

useEffect(() => {
function clickOnMap(evt) {
console.log("jh")
if (!map) return

const features = map.queryRenderedFeatures(evt.point, {
Expand Down Expand Up @@ -128,10 +127,10 @@ export function FieldsSourceAvailable({
if (bounds) {
const [[minX, minY], [maxX, maxY]] = bounds.toArray()
const bbox = {
minX: 0.9999 * minX,
maxX: 1.0001 * maxX,
minY: 0.9999 * minY,
maxY: 1.0001 * maxY,
minX: 0.9995 * minX,
maxX: 1.0005 * maxX,
minY: 0.9995 * minY,
maxY: 1.0005 * maxY,
}
try {
const iter = deserialize(url, bbox)
Expand Down
50 changes: 35 additions & 15 deletions fdm-app/app/components/custom/atlas/atlas-styles.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,47 @@
import type { LayerProps } from "react-map-gl"
import type {
FillLayerSpecification,
LayerProps,
SymbolLayerSpecification,
} from "react-map-gl"

export function getFieldsStyle(layerId: string): LayerProps & {
id: string
type: string
paint: {
"fill-color": string
"fill-opacity": number
"fill-outline-color": string
}
} {
const fieldsStyle = {
id: layerId,
export function getFieldsStyle(
layerId: string,
): LayerProps &
(
| ({
id: string
type: "fill"
paint: FillLayerSpecification["paint"]
})
| {
id: string
type: "symbol"
layout: SymbolLayerSpecification["layout"]
paint: SymbolLayerSpecification["paint"]
}
) {
const baseFieldsStyle: Omit<FillLayerSpecification, "id" | "source"> = {
type: "fill",
paint: {
"fill-color": "#93c5fd",
"fill-color": "#60a5fa",
"fill-opacity": 0.5,
"fill-outline-color": "#1e3a8a",
},
}
} as FillLayerSpecification // Cast to FillLayerSpecification to allow modification of paint

const fieldsStyle = {
...baseFieldsStyle,
id: layerId,
} as LayerProps & FillLayerSpecification // Cast to FillLayerSpecification to allow modification of paint

if (layerId === "fieldsSelected") {
fieldsStyle.paint["fill-color"] = "#fca5a5"
fieldsStyle.paint["fill-color"] = "#f43f5e"
fieldsStyle.paint["fill-opacity"] = 0.8
}
if (layerId === "fieldsSaved") {
fieldsStyle.paint["fill-color"] = "#10b981"
fieldsStyle.paint["fill-opacity"] = 0.8
}

return fieldsStyle
}
168 changes: 85 additions & 83 deletions fdm-app/app/components/custom/combobox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
import {
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
Expand All @@ -31,22 +30,25 @@ type optionType = {

interface ComboboxProps {
options: { value: string; label: string }[]
form: any
name: string
label: ReactNode
defaultValue?: optionType["value"]
disabled?: boolean
onChange: (value: string) => void
}

export function Combobox({
options,
form,
name,
label,
defaultValue,
disabled,
onChange
}: ComboboxProps) {
const [open, setOpen] = useState(false)
const [currentValue, setCurrentValue] = useState<string | undefined>(
defaultValue,
)

/** Map of option values to their labels for efficient lookup */
const optionsMap = useMemo(
Expand All @@ -67,85 +69,85 @@ export function Combobox({
)

return (
<FormField
control={form.control}
name={name}
disabled={disabled}
render={({ field }) => (
<FormItem>
<FormLabel>{label}</FormLabel>
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<FormControl>
<Button
variant="outline"
role="combobox"
aria-expanded={open}
name={name}
disabled={disabled}
className="w-full justify-between truncate focus-visible:ring-2"
aria-label={`Selecteer ${options.find((option) => option.value === field.value)?.label || defaultLabel || "Klik om te begin met typen..."}`}
aria-controls="combobox-options"
aria-haspopup="listbox"
>
{options.find(
(option) =>
option.value === field.value,
)?.label ||
defaultLabel ||
"Begin met typen..."}
<ChevronsUpDown className="opacity-50" />
</Button>
</FormControl>
</PopoverTrigger>
<PopoverContent
id="combobox-options"
className="w-full p-0"
<FormItem>
<FormLabel>{label}</FormLabel>
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<FormControl>
<Button
variant="outline"
role="combobox"
aria-expanded={open}
name={name}
disabled={disabled}
className="w-full justify-between truncate focus-visible:ring-2"
aria-label={`Selecteer ${
options.find(
(option) => option.value === currentValue,
)?.label ||
defaultLabel ||
"Klik om te begin met typen..."
}`}
aria-controls="combobox-options"
aria-haspopup="listbox"
>
Comment thread
SvenVw marked this conversation as resolved.
<Command>
<CommandInput
placeholder="Begin met typen..."
className="h-9"
/>
<CommandList>
<CommandEmpty>Niks gevonden</CommandEmpty>
<CommandGroup>
{options.map((option: optionType) => (
<CommandItem
value={option.label}
key={option.value}
disabled={disabled}
onSelect={() => {
form.setValue(
name,
option.value,
)
setOpen(false)
}}
>
<p className="text-pretty w-[350px]">
{option.label}
</p>
<Check
className={cn(
"ml-auto",
option.value ===
field.value
? "opacity-100"
: "opacity-0",
)}
/>
</CommandItem>
))}
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
<FormDescription />
<FormMessage />
</FormItem>
)}
/>
{options.find(
(option) => option.value === currentValue,
)?.label ||
defaultLabel ||
"Begin met typen..."}
<ChevronsUpDown className="opacity-50" />
</Button>
</FormControl>
</PopoverTrigger>
<PopoverContent
id="combobox-options"
className="w-full p-0"
>
<Command>
<CommandInput
placeholder="Begin met typen..."
className="h-9"
/>
<CommandList>
<CommandEmpty>Niks gevonden</CommandEmpty>
<CommandGroup>
{options.map((option: optionType) => (
<CommandItem
value={option.label}
key={option.value}
disabled={disabled}
onSelect={() => {
setCurrentValue(option.value)
onChange(option.value)
setOpen(false)
}}
>
<p className="text-pretty w-[350px]">
{option.label}
</p>
<Check
className={cn(
"ml-auto",
option.value === currentValue
? "opacity-100"
: "opacity-0",
)}
/>
</CommandItem>
))}
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
<input
type="hidden"
name={name}
value={currentValue}
/>
<FormDescription />
<FormMessage />
</FormItem>
)
}
}
Loading