Skip to content

Commit 8ab4ee8

Browse files
authored
Merge pull request #3217 from Dokploy/3216-production-environment-created-by-default-and-cant-be-removed-or-renamed
feat(environment): introduce isDefault flag for environments
2 parents 48be854 + 99aa34f commit 8ab4ee8

File tree

8 files changed

+7027
-50
lines changed

8 files changed

+7027
-50
lines changed

apps/dokploy/components/dashboard/project/advanced-environment-selector.tsx

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ export const AdvancedEnvironmentSelector = ({
102102
setName("");
103103
setDescription("");
104104
} catch (error) {
105-
toast.error("Failed to create environment");
105+
toast.error(
106+
`Failed to create environment: ${error instanceof Error ? error.message : error}`,
107+
);
106108
}
107109
};
108110

@@ -123,7 +125,9 @@ export const AdvancedEnvironmentSelector = ({
123125
setName("");
124126
setDescription("");
125127
} catch (error) {
126-
toast.error("Failed to update environment");
128+
toast.error(
129+
`Failed to update environment: ${error instanceof Error ? error.message : error}`,
130+
);
127131
}
128132
};
129133

@@ -140,15 +144,18 @@ export const AdvancedEnvironmentSelector = ({
140144
setIsDeleteDialogOpen(false);
141145
setSelectedEnvironment(null);
142146

143-
// Redirect to production if we deleted the current environment
147+
// Redirect to first available environment if we deleted the current environment
144148
if (selectedEnvironment.environmentId === currentEnvironmentId) {
145-
const productionEnv = environments?.find(
146-
(env) => env.name === "production",
149+
const firstEnv = environments?.find(
150+
(env) => env.environmentId !== selectedEnvironment.environmentId,
147151
);
148-
if (productionEnv) {
152+
if (firstEnv) {
149153
router.push(
150-
`/dashboard/project/${projectId}/environment/${productionEnv.environmentId}`,
154+
`/dashboard/project/${projectId}/environment/${firstEnv.environmentId}`,
151155
);
156+
} else {
157+
// No other environments, redirect to project page
158+
router.push(`/dashboard/project/${projectId}`);
152159
}
153160
}
154161
} catch (error) {
@@ -239,8 +246,8 @@ export const AdvancedEnvironmentSelector = ({
239246
)}
240247
</div>
241248
</DropdownMenuItem>
242-
{environment.name !== "production" && (
243-
<div className="flex items-center gap-1 px-2">
249+
<div className="flex items-center gap-1 px-2">
250+
{!environment.isDefault && (
244251
<Button
245252
variant="ghost"
246253
size="sm"
@@ -252,22 +259,21 @@ export const AdvancedEnvironmentSelector = ({
252259
>
253260
<PencilIcon className="h-3 w-3" />
254261
</Button>
255-
256-
{canDeleteEnvironments && (
257-
<Button
258-
variant="ghost"
259-
size="sm"
260-
className="h-6 w-6 p-0 text-red-600 hover:text-red-700"
261-
onClick={(e) => {
262-
e.stopPropagation();
263-
openDeleteDialog(environment);
264-
}}
265-
>
266-
<TrashIcon className="h-3 w-3" />
267-
</Button>
268-
)}
269-
</div>
270-
)}
262+
)}
263+
{canDeleteEnvironments && !environment.isDefault && (
264+
<Button
265+
variant="ghost"
266+
size="sm"
267+
className="h-6 w-6 p-0 text-red-600 hover:text-red-700"
268+
onClick={(e) => {
269+
e.stopPropagation();
270+
openDeleteDialog(environment);
271+
}}
272+
>
273+
<TrashIcon className="h-3 w-3" />
274+
</Button>
275+
)}
276+
</div>
271277
</div>
272278
);
273279
})}

apps/dokploy/components/dashboard/search-command.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,24 +89,26 @@ export const SearchCommand = () => {
8989
<CommandGroup heading={"Projects"}>
9090
<CommandList>
9191
{data?.map((project) => {
92-
const productionEnvironment = project.environments.find(
93-
(environment) => environment.name === "production",
94-
);
92+
// Find default environment, or fall back to first environment
93+
const defaultEnvironment =
94+
project.environments.find(
95+
(environment) => environment.isDefault,
96+
) || project?.environments?.[0];
9597

96-
if (!productionEnvironment) return null;
98+
if (!defaultEnvironment) return null;
9799

98100
return (
99101
<CommandItem
100102
key={project.projectId}
101103
onSelect={() => {
102104
router.push(
103-
`/dashboard/project/${project.projectId}/environment/${productionEnvironment!.environmentId}`,
105+
`/dashboard/project/${project.projectId}/environment/${defaultEnvironment.environmentId}`,
104106
);
105107
setOpen(false);
106108
}}
107109
>
108110
<BookIcon className="size-4 text-muted-foreground mr-2" />
109-
{project.name} / {productionEnvironment!.name}
111+
{project.name} / {defaultEnvironment.name}
110112
</CommandItem>
111113
);
112114
})}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
ALTER TABLE "environment" ADD COLUMN "isDefault" boolean DEFAULT false NOT NULL;
2+
3+
-- Set isDefault to true for existing production environments
4+
UPDATE "environment" SET "isDefault" = true WHERE "name" = 'production';

0 commit comments

Comments
 (0)