mirror of
https://github.com/andwati/dokploy.git
synced 2026-11-05 11:42:17 +00:00
feat(destinations): add additionalFlags field for destination settings
- Introduced an optional `additionalFlags` field in the destination schema to allow users to specify extra parameters. - Updated the form in the dashboard to include a textarea for entering additional flags. - Modified the API router to handle the new `additionalFlags` input when creating or updating destinations. - Adjusted database schema to accommodate the new field in the destination table.
This commit is contained in:
@@ -24,6 +24,7 @@ import {
|
|||||||
FormMessage,
|
FormMessage,
|
||||||
} from "@/components/ui/form";
|
} from "@/components/ui/form";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
import {
|
import {
|
||||||
Select,
|
Select,
|
||||||
SelectContent,
|
SelectContent,
|
||||||
@@ -46,6 +47,7 @@ const addDestination = z.object({
|
|||||||
region: z.string(),
|
region: z.string(),
|
||||||
endpoint: z.string().min(1, "Endpoint is required"),
|
endpoint: z.string().min(1, "Endpoint is required"),
|
||||||
serverId: z.string().optional(),
|
serverId: z.string().optional(),
|
||||||
|
additionalFlags: z.array(z.string()).optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
type AddDestination = z.infer<typeof addDestination>;
|
type AddDestination = z.infer<typeof addDestination>;
|
||||||
@@ -89,6 +91,7 @@ export const HandleDestinations = ({ destinationId }: Props) => {
|
|||||||
region: "",
|
region: "",
|
||||||
secretAccessKey: "",
|
secretAccessKey: "",
|
||||||
endpoint: "",
|
endpoint: "",
|
||||||
|
additionalFlags: [],
|
||||||
},
|
},
|
||||||
resolver: zodResolver(addDestination),
|
resolver: zodResolver(addDestination),
|
||||||
});
|
});
|
||||||
@@ -102,6 +105,7 @@ export const HandleDestinations = ({ destinationId }: Props) => {
|
|||||||
bucket: destination.bucket,
|
bucket: destination.bucket,
|
||||||
region: destination.region,
|
region: destination.region,
|
||||||
endpoint: destination.endpoint,
|
endpoint: destination.endpoint,
|
||||||
|
additionalFlags: destination.additionalFlags ?? [],
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
form.reset();
|
form.reset();
|
||||||
@@ -118,6 +122,7 @@ export const HandleDestinations = ({ destinationId }: Props) => {
|
|||||||
region: data.region,
|
region: data.region,
|
||||||
secretAccessKey: data.secretAccessKey,
|
secretAccessKey: data.secretAccessKey,
|
||||||
destinationId: destinationId || "",
|
destinationId: destinationId || "",
|
||||||
|
additionalFlags: data.additionalFlags ?? [],
|
||||||
})
|
})
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
toast.success(`Destination ${destinationId ? "Updated" : "Created"}`);
|
toast.success(`Destination ${destinationId ? "Updated" : "Created"}`);
|
||||||
@@ -179,6 +184,7 @@ export const HandleDestinations = ({ destinationId }: Props) => {
|
|||||||
region,
|
region,
|
||||||
secretAccessKey: secretKey,
|
secretAccessKey: secretKey,
|
||||||
serverId,
|
serverId,
|
||||||
|
additionalFlags: form.getValues("additionalFlags") ?? [],
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
toast.success("Connection Success");
|
toast.success("Connection Success");
|
||||||
@@ -358,6 +364,33 @@ export const HandleDestinations = ({ destinationId }: Props) => {
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="additionalFlags"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Additional Flags (Optional)</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Textarea
|
||||||
|
placeholder={
|
||||||
|
"--s3-sign-accept-encoding=false\n--s3-chunk-size=50M"
|
||||||
|
}
|
||||||
|
className="h-20"
|
||||||
|
value={(field.value || []).join("\n")}
|
||||||
|
onChange={(e) =>
|
||||||
|
field.onChange(
|
||||||
|
e.target.value
|
||||||
|
.split("\n")
|
||||||
|
.map((f) => f.trim())
|
||||||
|
.filter((f) => f.length > 0),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<DialogFooter
|
<DialogFooter
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE "destination" ADD COLUMN "additionalFlags" text[];
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1086,6 +1086,13 @@
|
|||||||
"when": 1774337356154,
|
"when": 1774337356154,
|
||||||
"tag": "0154_careful_eternals",
|
"tag": "0154_careful_eternals",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 155,
|
||||||
|
"version": "7",
|
||||||
|
"when": 1774794547865,
|
||||||
|
"tag": "0155_careless_clea",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -47,8 +47,15 @@ export const destinationRouter = createTRPCRouter({
|
|||||||
testConnection: withPermission("destination", "create")
|
testConnection: withPermission("destination", "create")
|
||||||
.input(apiCreateDestination)
|
.input(apiCreateDestination)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
const { secretAccessKey, bucket, region, endpoint, accessKey, provider } =
|
const {
|
||||||
input;
|
secretAccessKey,
|
||||||
|
bucket,
|
||||||
|
region,
|
||||||
|
endpoint,
|
||||||
|
accessKey,
|
||||||
|
provider,
|
||||||
|
additionalFlags,
|
||||||
|
} = input;
|
||||||
try {
|
try {
|
||||||
const rcloneFlags = [
|
const rcloneFlags = [
|
||||||
`--s3-access-key-id="${accessKey}"`,
|
`--s3-access-key-id="${accessKey}"`,
|
||||||
@@ -65,6 +72,9 @@ export const destinationRouter = createTRPCRouter({
|
|||||||
if (provider) {
|
if (provider) {
|
||||||
rcloneFlags.unshift(`--s3-provider="${provider}"`);
|
rcloneFlags.unshift(`--s3-provider="${provider}"`);
|
||||||
}
|
}
|
||||||
|
if (additionalFlags?.length) {
|
||||||
|
rcloneFlags.push(...additionalFlags);
|
||||||
|
}
|
||||||
const rcloneDestination = `:s3:${bucket}`;
|
const rcloneDestination = `:s3:${bucket}`;
|
||||||
const rcloneCommand = `rclone ls ${rcloneFlags.join(" ")} "${rcloneDestination}"`;
|
const rcloneCommand = `rclone ls ${rcloneFlags.join(" ")} "${rcloneDestination}"`;
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ export const destinations = pgTable("destination", {
|
|||||||
bucket: text("bucket").notNull(),
|
bucket: text("bucket").notNull(),
|
||||||
region: text("region").notNull(),
|
region: text("region").notNull(),
|
||||||
endpoint: text("endpoint").notNull(),
|
endpoint: text("endpoint").notNull(),
|
||||||
|
additionalFlags: text("additionalFlags").array(),
|
||||||
organizationId: text("organizationId")
|
organizationId: text("organizationId")
|
||||||
.notNull()
|
.notNull()
|
||||||
.references(() => organization.id, { onDelete: "cascade" }),
|
.references(() => organization.id, { onDelete: "cascade" }),
|
||||||
@@ -44,6 +45,7 @@ const createSchema = createInsertSchema(destinations, {
|
|||||||
endpoint: z.string(),
|
endpoint: z.string(),
|
||||||
secretAccessKey: z.string(),
|
secretAccessKey: z.string(),
|
||||||
region: z.string(),
|
region: z.string(),
|
||||||
|
additionalFlags: z.array(z.string()).default([]),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const apiCreateDestination = createSchema
|
export const apiCreateDestination = createSchema
|
||||||
@@ -55,6 +57,7 @@ export const apiCreateDestination = createSchema
|
|||||||
region: true,
|
region: true,
|
||||||
endpoint: true,
|
endpoint: true,
|
||||||
secretAccessKey: true,
|
secretAccessKey: true,
|
||||||
|
additionalFlags: true,
|
||||||
})
|
})
|
||||||
.required()
|
.required()
|
||||||
.extend({
|
.extend({
|
||||||
@@ -81,6 +84,7 @@ export const apiUpdateDestination = createSchema
|
|||||||
secretAccessKey: true,
|
secretAccessKey: true,
|
||||||
destinationId: true,
|
destinationId: true,
|
||||||
provider: true,
|
provider: true,
|
||||||
|
additionalFlags: true,
|
||||||
})
|
})
|
||||||
.required()
|
.required()
|
||||||
.extend({
|
.extend({
|
||||||
|
|||||||
@@ -79,6 +79,10 @@ export const getS3Credentials = (destination: Destination) => {
|
|||||||
rcloneFlags.unshift(`--s3-provider="${provider}"`);
|
rcloneFlags.unshift(`--s3-provider="${provider}"`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (destination.additionalFlags?.length) {
|
||||||
|
rcloneFlags.push(...destination.additionalFlags);
|
||||||
|
}
|
||||||
|
|
||||||
return rcloneFlags;
|
return rcloneFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user