Skip to content

Commit e1401a4

Browse files
authored
fix: save dockerfile, root dir, port, command, and healthcheck settings to all environments (#5293)
Settings without per-environment UI were only saving to the currently active environment (defaults to production). This meant preview and other environments would silently get out of sync.
1 parent 652c5e5 commit e1401a4

File tree

6 files changed

+47
-16
lines changed

6 files changed

+47
-16
lines changed

web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/settings/components/build-settings/dockerfile-settings.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { collection } from "@/lib/collections";
21
import { zodResolver } from "@hookform/resolvers/zod";
32
import { FileSettings } from "@unkey/icons";
43
import { FormInput } from "@unkey/ui";
54
import { useForm, useWatch } from "react-hook-form";
65
import { z } from "zod";
76
import { useEnvironmentSettings } from "../../environment-provider";
7+
import { useUpdateAllEnvironments } from "../../hooks/use-update-all-environments";
88
import { FormSettingCard, resolveSaveState } from "../shared/form-setting-card";
99

1010
const dockerfileSchema = z.object({
@@ -13,7 +13,8 @@ const dockerfileSchema = z.object({
1313

1414
export const Dockerfile = () => {
1515
const { settings, variant } = useEnvironmentSettings();
16-
const { environmentId, dockerfile: defaultValue } = settings;
16+
const { dockerfile: defaultValue } = settings;
17+
const updateAllEnvironments = useUpdateAllEnvironments();
1718

1819
const {
1920
register,
@@ -35,7 +36,7 @@ export const Dockerfile = () => {
3536
]);
3637

3738
const onSubmit = async (values: z.infer<typeof dockerfileSchema>) => {
38-
collection.environmentSettings.update(environmentId, (draft) => {
39+
updateAllEnvironments((draft) => {
3940
draft.dockerfile = values.dockerfile;
4041
});
4142
};

web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/settings/components/build-settings/root-directory-settings.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { collection } from "@/lib/collections";
21
import { zodResolver } from "@hookform/resolvers/zod";
32
import { FolderLink } from "@unkey/icons";
43
import { FormInput } from "@unkey/ui";
54
import { useForm, useWatch } from "react-hook-form";
65
import { z } from "zod";
76
import { useEnvironmentSettings } from "../../environment-provider";
7+
import { useUpdateAllEnvironments } from "../../hooks/use-update-all-environments";
88
import { FormSettingCard, resolveSaveState } from "../shared/form-setting-card";
99

1010
const rootDirectorySchema = z.object({
@@ -13,7 +13,8 @@ const rootDirectorySchema = z.object({
1313

1414
export const RootDirectory = () => {
1515
const { settings, variant } = useEnvironmentSettings();
16-
const { environmentId, dockerContext: defaultValue } = settings;
16+
const { dockerContext: defaultValue } = settings;
17+
const updateAllEnvironments = useUpdateAllEnvironments();
1718

1819
const {
1920
register,
@@ -35,7 +36,7 @@ export const RootDirectory = () => {
3536
]);
3637

3738
const onSubmit = async (values: z.infer<typeof rootDirectorySchema>) => {
38-
collection.environmentSettings.update(environmentId, (draft) => {
39+
updateAllEnvironments((draft) => {
3940
draft.dockerContext = values.dockerContext;
4041
});
4142
};

web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/settings/components/runtime-settings/command.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
"use client";
22

3-
import { collection } from "@/lib/collections";
43
import { zodResolver } from "@hookform/resolvers/zod";
54
import { SquareTerminal } from "@unkey/icons";
65
import { FormTextarea, InfoTooltip } from "@unkey/ui";
76
import { useEffect } from "react";
87
import { useForm, useWatch } from "react-hook-form";
98
import { z } from "zod";
109
import { useEnvironmentSettings } from "../../environment-provider";
10+
import { useUpdateAllEnvironments } from "../../hooks/use-update-all-environments";
1111
import { FormSettingCard, resolveSaveState } from "../shared/form-setting-card";
1212

1313
const commandSchema = z.object({
@@ -18,7 +18,8 @@ type CommandFormValues = z.infer<typeof commandSchema>;
1818

1919
export const Command = () => {
2020
const { settings, variant } = useEnvironmentSettings();
21-
const { command, environmentId } = settings;
21+
const { command } = settings;
22+
const updateAllEnvironments = useUpdateAllEnvironments();
2223
const defaultCommand = command.join(" ");
2324

2425
const {
@@ -49,7 +50,7 @@ export const Command = () => {
4950
const onSubmit = async (values: CommandFormValues) => {
5051
const trimmed = values.command.trim();
5152
const command = trimmed === "" ? [] : trimmed.split(/\s+/).filter(Boolean);
52-
collection.environmentSettings.update(environmentId, (draft) => {
53+
updateAllEnvironments((draft) => {
5354
draft.command = command;
5455
});
5556
};

web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/settings/components/runtime-settings/healthcheck/index.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
"use client";
22

3-
import { collection } from "@/lib/collections";
43
import { zodResolver } from "@hookform/resolvers/zod";
54
import { ChevronDown, HeartPulse } from "@unkey/icons";
65
import {
@@ -14,6 +13,7 @@ import {
1413
import { useEffect } from "react";
1514
import { Controller, useForm } from "react-hook-form";
1615
import { useEnvironmentSettings } from "../../../environment-provider";
16+
import { useUpdateAllEnvironments } from "../../../hooks/use-update-all-environments";
1717
import { FormSettingCard, resolveSaveState } from "../../shared/form-setting-card";
1818
import { RemoveButton } from "../../shared/remove-button";
1919
import { MethodBadge } from "./method-badge";
@@ -22,7 +22,8 @@ import { intervalToSeconds, secondsToInterval } from "./utils";
2222

2323
export const Healthcheck = () => {
2424
const { settings, variant } = useEnvironmentSettings();
25-
const { healthcheck, environmentId } = settings;
25+
const { healthcheck } = settings;
26+
const updateAllEnvironments = useUpdateAllEnvironments();
2627

2728
const defaultValues: HealthcheckFormValues = {
2829
method: healthcheck?.method ?? "GET",
@@ -48,7 +49,7 @@ export const Healthcheck = () => {
4849
}, [defaultValues.method, defaultValues.path, defaultValues.interval, reset]);
4950

5051
const onSubmit = async (values: HealthcheckFormValues) => {
51-
collection.environmentSettings.update(environmentId, (draft) => {
52+
updateAllEnvironments((draft) => {
5253
draft.healthcheck =
5354
values.path.trim() === ""
5455
? null
@@ -64,7 +65,7 @@ export const Healthcheck = () => {
6465
};
6566

6667
const handleRemove = () => {
67-
collection.environmentSettings.update(environmentId, (draft) => {
68+
updateAllEnvironments((draft) => {
6869
draft.healthcheck = null;
6970
});
7071
reset({ method: "GET", path: "", interval: "" });

web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/settings/components/runtime-settings/port-settings.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { collection } from "@/lib/collections";
21
import { zodResolver } from "@hookform/resolvers/zod";
32
import { NumberInput } from "@unkey/icons";
43
import { FormInput } from "@unkey/ui";
54
import { useForm, useWatch } from "react-hook-form";
65
import { z } from "zod";
76
import { useEnvironmentSettings } from "../../environment-provider";
7+
import { useUpdateAllEnvironments } from "../../hooks/use-update-all-environments";
88
import { FormSettingCard, resolveSaveState } from "../shared/form-setting-card";
99

1010
const portSchema = z.object({
@@ -13,7 +13,8 @@ const portSchema = z.object({
1313

1414
export const Port = () => {
1515
const { settings, variant } = useEnvironmentSettings();
16-
const { environmentId, port: defaultValue } = settings;
16+
const { port: defaultValue } = settings;
17+
const updateAllEnvironments = useUpdateAllEnvironments();
1718

1819
const {
1920
register,
@@ -35,7 +36,7 @@ export const Port = () => {
3536
]);
3637

3738
const onSubmit = async (values: z.infer<typeof portSchema>) => {
38-
collection.environmentSettings.update(environmentId, (draft) => {
39+
updateAllEnvironments((draft) => {
3940
draft.port = values.port;
4041
});
4142
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"use client";
2+
3+
import { collection } from "@/lib/collections";
4+
import type { EnvironmentSettings } from "@/lib/collections/deploy/environment-settings";
5+
import { useCallback } from "react";
6+
import { useProjectData } from "../../data-provider";
7+
8+
/**
9+
* Returns a function that applies a settings mutation to every environment.
10+
*
11+
* Use this for settings that don't have per-environment UI (e.g. dockerfile,
12+
* root directory, port, command, healthcheck) so they stay consistent across
13+
* all environments.
14+
*/
15+
export function useUpdateAllEnvironments() {
16+
const { environments } = useProjectData();
17+
18+
return useCallback(
19+
(updater: (draft: EnvironmentSettings) => void) => {
20+
for (const env of environments) {
21+
collection.environmentSettings.update(env.id, updater);
22+
}
23+
},
24+
[environments],
25+
);
26+
}

0 commit comments

Comments
 (0)