mirror of
https://github.com/moghtech/komodo.git
synced 2026-03-11 17:44:19 -05:00
stack don't show Git Repo config is file contents defined in UI
This commit is contained in:
@@ -47,8 +47,9 @@ export const StackConfig = ({
|
||||
if (!config) return null;
|
||||
|
||||
const disabled = global_disabled || perms !== Types.PermissionLevel.Write;
|
||||
|
||||
const files_on_host = update.files_on_host ?? config.files_on_host;
|
||||
const ui_file_contents =
|
||||
(update.file_contents ?? config.file_contents ?? "").length > 0;
|
||||
|
||||
return (
|
||||
<Config
|
||||
@@ -317,274 +318,282 @@ export const StackConfig = ({
|
||||
},
|
||||
},
|
||||
],
|
||||
"Git Repo": !files_on_host && [
|
||||
{
|
||||
label: "Git",
|
||||
description:
|
||||
"Provide config for repo-based compose files. Not necessary if file contents are configured in UI.",
|
||||
components: {
|
||||
git_provider: (provider, set) => {
|
||||
const https = update.git_https ?? config.git_https;
|
||||
return (
|
||||
<ProviderSelectorConfig
|
||||
account_type="git"
|
||||
selected={provider}
|
||||
disabled={disabled}
|
||||
onSelect={(git_provider) => set({ git_provider })}
|
||||
https={https}
|
||||
onHttpsSwitch={() => set({ git_https: !https })}
|
||||
/>
|
||||
);
|
||||
},
|
||||
git_account: (value, set) => {
|
||||
const server_id = update.server_id || config.server_id;
|
||||
return (
|
||||
<AccountSelectorConfig
|
||||
id={server_id}
|
||||
type={server_id ? "Server" : "None"}
|
||||
account_type="git"
|
||||
provider={update.git_provider ?? config.git_provider}
|
||||
selected={value}
|
||||
onSelect={(git_account) => set({ git_account })}
|
||||
disabled={disabled}
|
||||
placeholder="None"
|
||||
/>
|
||||
);
|
||||
},
|
||||
repo: {
|
||||
placeholder: "Enter repo",
|
||||
description:
|
||||
"The repo path on the provider. {namespace}/{repo_name}",
|
||||
},
|
||||
branch: {
|
||||
placeholder: "Enter branch",
|
||||
description: "Select a custom branch, or default to 'main'.",
|
||||
},
|
||||
commit: {
|
||||
placeholder: "Enter a specific commit hash. Optional.",
|
||||
description:
|
||||
"Switch to a specific hash after cloning the branch.",
|
||||
"Git Repo": !files_on_host &&
|
||||
!ui_file_contents && [
|
||||
{
|
||||
label: "Git",
|
||||
description:
|
||||
"Provide config for repo-based compose files. Not necessary if file contents are configured in UI.",
|
||||
components: {
|
||||
git_provider: (provider, set) => {
|
||||
const https = update.git_https ?? config.git_https;
|
||||
return (
|
||||
<ProviderSelectorConfig
|
||||
account_type="git"
|
||||
selected={provider}
|
||||
disabled={disabled}
|
||||
onSelect={(git_provider) => set({ git_provider })}
|
||||
https={https}
|
||||
onHttpsSwitch={() => set({ git_https: !https })}
|
||||
/>
|
||||
);
|
||||
},
|
||||
git_account: (value, set) => {
|
||||
const server_id = update.server_id || config.server_id;
|
||||
return (
|
||||
<AccountSelectorConfig
|
||||
id={server_id}
|
||||
type={server_id ? "Server" : "None"}
|
||||
account_type="git"
|
||||
provider={update.git_provider ?? config.git_provider}
|
||||
selected={value}
|
||||
onSelect={(git_account) => set({ git_account })}
|
||||
disabled={disabled}
|
||||
placeholder="None"
|
||||
/>
|
||||
);
|
||||
},
|
||||
repo: {
|
||||
placeholder: "Enter repo",
|
||||
description:
|
||||
"The repo path on the provider. {namespace}/{repo_name}",
|
||||
},
|
||||
branch: {
|
||||
placeholder: "Enter branch",
|
||||
description: "Select a custom branch, or default to 'main'.",
|
||||
},
|
||||
commit: {
|
||||
placeholder: "Enter a specific commit hash. Optional.",
|
||||
description:
|
||||
"Switch to a specific hash after cloning the branch.",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "Run Path",
|
||||
labelHidden: true,
|
||||
components: {
|
||||
run_directory: {
|
||||
placeholder: "./",
|
||||
description:
|
||||
"Set the cwd when running compose up command. Relative to the repo root.",
|
||||
boldLabel: true,
|
||||
{
|
||||
label: "Run Path",
|
||||
labelHidden: true,
|
||||
components: {
|
||||
run_directory: {
|
||||
placeholder: "./",
|
||||
description:
|
||||
"Set the cwd when running compose up command. Relative to the repo root.",
|
||||
boldLabel: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "File Paths",
|
||||
description:
|
||||
"Add files to include using 'docker compose -f'. If empty, uses 'compose.yaml'. Relative to 'Run Directory'.",
|
||||
contentHidden:
|
||||
(update.file_paths ?? config.file_paths)?.length === 0,
|
||||
actions: !disabled && (
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() =>
|
||||
set((update) => ({
|
||||
...update,
|
||||
file_paths: [
|
||||
...(update.file_paths ?? config.file_paths ?? []),
|
||||
"",
|
||||
],
|
||||
}))
|
||||
}
|
||||
className="flex items-center gap-2 w-[200px]"
|
||||
>
|
||||
<PlusCircle className="w-4 h-4" />
|
||||
Add File
|
||||
</Button>
|
||||
),
|
||||
components: {
|
||||
file_paths: (value, set) => (
|
||||
<InputList
|
||||
field="file_paths"
|
||||
values={value ?? []}
|
||||
set={set}
|
||||
disabled={disabled}
|
||||
placeholder="compose.yaml"
|
||||
/>
|
||||
{
|
||||
label: "File Paths",
|
||||
description:
|
||||
"Add files to include using 'docker compose -f'. If empty, uses 'compose.yaml'. Relative to 'Run Directory'.",
|
||||
contentHidden:
|
||||
(update.file_paths ?? config.file_paths)?.length === 0,
|
||||
actions: !disabled && (
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() =>
|
||||
set((update) => ({
|
||||
...update,
|
||||
file_paths: [
|
||||
...(update.file_paths ?? config.file_paths ?? []),
|
||||
"",
|
||||
],
|
||||
}))
|
||||
}
|
||||
className="flex items-center gap-2 w-[200px]"
|
||||
>
|
||||
<PlusCircle className="w-4 h-4" />
|
||||
Add File
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "Git Webhooks",
|
||||
description:
|
||||
"Configure your repo provider to send webhooks to Monitor",
|
||||
components: {
|
||||
["Guard" as any]: () => {
|
||||
if (update.branch ?? config.branch) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<ConfigItem label="Configure Branch">
|
||||
<div>Must configure Branch before webhooks will work.</div>
|
||||
</ConfigItem>
|
||||
);
|
||||
},
|
||||
["Refresh" as any]: () =>
|
||||
(update.branch ?? config.branch) && (
|
||||
<ConfigItem label="Refresh Cache">
|
||||
<CopyGithubWebhook path={`/stack/${id}/refresh`} />
|
||||
</ConfigItem>
|
||||
components: {
|
||||
file_paths: (value, set) => (
|
||||
<InputList
|
||||
field="file_paths"
|
||||
values={value ?? []}
|
||||
set={set}
|
||||
disabled={disabled}
|
||||
placeholder="compose.yaml"
|
||||
/>
|
||||
),
|
||||
["Deploy" as any]: () =>
|
||||
(update.branch ?? config.branch) && (
|
||||
<ConfigItem label="Auto Redeploy">
|
||||
<CopyGithubWebhook path={`/stack/${id}/deploy`} />
|
||||
</ConfigItem>
|
||||
),
|
||||
webhook_enabled:
|
||||
!!(update.branch ?? config.branch) &&
|
||||
webhooks !== undefined &&
|
||||
!webhooks.managed,
|
||||
webhook_secret: {
|
||||
description:
|
||||
"Provide a custom webhook secret for this resource, or use the global default.",
|
||||
placeholder: "Input custom secret",
|
||||
},
|
||||
["managed" as any]: () => {
|
||||
const inv = useInvalidate();
|
||||
const { toast } = useToast();
|
||||
const { mutate: createWebhook, isPending: createPending } =
|
||||
useWrite("CreateStackWebhook", {
|
||||
onSuccess: () => {
|
||||
toast({ title: "Webhook Created" });
|
||||
inv(["GetStackWebhooksEnabled", { stack: id }]);
|
||||
},
|
||||
});
|
||||
const { mutate: deleteWebhook, isPending: deletePending } =
|
||||
useWrite("DeleteStackWebhook", {
|
||||
onSuccess: () => {
|
||||
toast({ title: "Webhook Deleted" });
|
||||
inv(["GetStackWebhooksEnabled", { stack: id }]);
|
||||
},
|
||||
});
|
||||
|
||||
if (
|
||||
!(update.branch ?? config.branch) ||
|
||||
!webhooks ||
|
||||
!webhooks.managed
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<ConfigItem label="Manage Webhook">
|
||||
{webhooks.deploy_enabled && (
|
||||
<div className="flex items-center gap-4 flex-wrap">
|
||||
<div className="flex items-center gap-2">
|
||||
Incoming webhook is{" "}
|
||||
<div
|
||||
className={text_color_class_by_intention("Good")}
|
||||
>
|
||||
ENABLED
|
||||
</div>
|
||||
and will trigger
|
||||
<div
|
||||
className={text_color_class_by_intention("Neutral")}
|
||||
>
|
||||
DEPLOY
|
||||
</div>
|
||||
</div>
|
||||
<ConfirmButton
|
||||
title="Disable"
|
||||
icon={<Ban className="w-4 h-4" />}
|
||||
variant="destructive"
|
||||
onClick={() =>
|
||||
deleteWebhook({
|
||||
stack: id,
|
||||
action: Types.StackWebhookAction.Deploy,
|
||||
})
|
||||
}
|
||||
loading={deletePending}
|
||||
disabled={disabled || deletePending}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{!webhooks.deploy_enabled && webhooks.refresh_enabled && (
|
||||
<div className="flex items-center gap-4 flex-wrap">
|
||||
<div className="flex items-center gap-2">
|
||||
Incoming webhook is{" "}
|
||||
<div
|
||||
className={text_color_class_by_intention("Good")}
|
||||
>
|
||||
ENABLED
|
||||
</div>
|
||||
and will trigger
|
||||
<div
|
||||
className={text_color_class_by_intention("Neutral")}
|
||||
>
|
||||
REFRESH
|
||||
</div>
|
||||
</div>
|
||||
<ConfirmButton
|
||||
title="Disable"
|
||||
icon={<Ban className="w-4 h-4" />}
|
||||
variant="destructive"
|
||||
onClick={() =>
|
||||
deleteWebhook({
|
||||
stack: id,
|
||||
action: Types.StackWebhookAction.Refresh,
|
||||
})
|
||||
}
|
||||
loading={deletePending}
|
||||
disabled={disabled || deletePending}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{!webhooks.deploy_enabled && !webhooks.refresh_enabled && (
|
||||
<div className="flex items-center gap-4 flex-wrap">
|
||||
<div className="flex items-center gap-2">
|
||||
Incoming webhook is{" "}
|
||||
<div
|
||||
className={text_color_class_by_intention(
|
||||
"Critical"
|
||||
)}
|
||||
>
|
||||
DISABLED
|
||||
</div>
|
||||
</div>
|
||||
<ConfirmButton
|
||||
title="Enable Deploy"
|
||||
icon={<CirclePlus className="w-4 h-4" />}
|
||||
onClick={() =>
|
||||
createWebhook({
|
||||
stack: id,
|
||||
action: Types.StackWebhookAction.Deploy,
|
||||
})
|
||||
}
|
||||
loading={createPending}
|
||||
disabled={disabled || createPending}
|
||||
/>
|
||||
<ConfirmButton
|
||||
title="Enable Refresh"
|
||||
icon={<CirclePlus className="w-4 h-4" />}
|
||||
onClick={() =>
|
||||
createWebhook({
|
||||
stack: id,
|
||||
action: Types.StackWebhookAction.Refresh,
|
||||
})
|
||||
}
|
||||
loading={createPending}
|
||||
disabled={disabled || createPending}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</ConfigItem>
|
||||
);
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
{
|
||||
label: "Git Webhooks",
|
||||
description:
|
||||
"Configure your repo provider to send webhooks to Monitor",
|
||||
components: {
|
||||
["Guard" as any]: () => {
|
||||
if (update.branch ?? config.branch) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<ConfigItem label="Configure Branch">
|
||||
<div>
|
||||
Must configure Branch before webhooks will work.
|
||||
</div>
|
||||
</ConfigItem>
|
||||
);
|
||||
},
|
||||
["Refresh" as any]: () =>
|
||||
(update.branch ?? config.branch) && (
|
||||
<ConfigItem label="Refresh Cache">
|
||||
<CopyGithubWebhook path={`/stack/${id}/refresh`} />
|
||||
</ConfigItem>
|
||||
),
|
||||
["Deploy" as any]: () =>
|
||||
(update.branch ?? config.branch) && (
|
||||
<ConfigItem label="Auto Redeploy">
|
||||
<CopyGithubWebhook path={`/stack/${id}/deploy`} />
|
||||
</ConfigItem>
|
||||
),
|
||||
webhook_enabled:
|
||||
!!(update.branch ?? config.branch) &&
|
||||
webhooks !== undefined &&
|
||||
!webhooks.managed,
|
||||
webhook_secret: {
|
||||
description:
|
||||
"Provide a custom webhook secret for this resource, or use the global default.",
|
||||
placeholder: "Input custom secret",
|
||||
},
|
||||
["managed" as any]: () => {
|
||||
const inv = useInvalidate();
|
||||
const { toast } = useToast();
|
||||
const { mutate: createWebhook, isPending: createPending } =
|
||||
useWrite("CreateStackWebhook", {
|
||||
onSuccess: () => {
|
||||
toast({ title: "Webhook Created" });
|
||||
inv(["GetStackWebhooksEnabled", { stack: id }]);
|
||||
},
|
||||
});
|
||||
const { mutate: deleteWebhook, isPending: deletePending } =
|
||||
useWrite("DeleteStackWebhook", {
|
||||
onSuccess: () => {
|
||||
toast({ title: "Webhook Deleted" });
|
||||
inv(["GetStackWebhooksEnabled", { stack: id }]);
|
||||
},
|
||||
});
|
||||
|
||||
if (
|
||||
!(update.branch ?? config.branch) ||
|
||||
!webhooks ||
|
||||
!webhooks.managed
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<ConfigItem label="Manage Webhook">
|
||||
{webhooks.deploy_enabled && (
|
||||
<div className="flex items-center gap-4 flex-wrap">
|
||||
<div className="flex items-center gap-2">
|
||||
Incoming webhook is{" "}
|
||||
<div
|
||||
className={text_color_class_by_intention("Good")}
|
||||
>
|
||||
ENABLED
|
||||
</div>
|
||||
and will trigger
|
||||
<div
|
||||
className={text_color_class_by_intention(
|
||||
"Neutral"
|
||||
)}
|
||||
>
|
||||
DEPLOY
|
||||
</div>
|
||||
</div>
|
||||
<ConfirmButton
|
||||
title="Disable"
|
||||
icon={<Ban className="w-4 h-4" />}
|
||||
variant="destructive"
|
||||
onClick={() =>
|
||||
deleteWebhook({
|
||||
stack: id,
|
||||
action: Types.StackWebhookAction.Deploy,
|
||||
})
|
||||
}
|
||||
loading={deletePending}
|
||||
disabled={disabled || deletePending}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{!webhooks.deploy_enabled && webhooks.refresh_enabled && (
|
||||
<div className="flex items-center gap-4 flex-wrap">
|
||||
<div className="flex items-center gap-2">
|
||||
Incoming webhook is{" "}
|
||||
<div
|
||||
className={text_color_class_by_intention("Good")}
|
||||
>
|
||||
ENABLED
|
||||
</div>
|
||||
and will trigger
|
||||
<div
|
||||
className={text_color_class_by_intention(
|
||||
"Neutral"
|
||||
)}
|
||||
>
|
||||
REFRESH
|
||||
</div>
|
||||
</div>
|
||||
<ConfirmButton
|
||||
title="Disable"
|
||||
icon={<Ban className="w-4 h-4" />}
|
||||
variant="destructive"
|
||||
onClick={() =>
|
||||
deleteWebhook({
|
||||
stack: id,
|
||||
action: Types.StackWebhookAction.Refresh,
|
||||
})
|
||||
}
|
||||
loading={deletePending}
|
||||
disabled={disabled || deletePending}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{!webhooks.deploy_enabled &&
|
||||
!webhooks.refresh_enabled && (
|
||||
<div className="flex items-center gap-4 flex-wrap">
|
||||
<div className="flex items-center gap-2">
|
||||
Incoming webhook is{" "}
|
||||
<div
|
||||
className={text_color_class_by_intention(
|
||||
"Critical"
|
||||
)}
|
||||
>
|
||||
DISABLED
|
||||
</div>
|
||||
</div>
|
||||
<ConfirmButton
|
||||
title="Enable Deploy"
|
||||
icon={<CirclePlus className="w-4 h-4" />}
|
||||
onClick={() =>
|
||||
createWebhook({
|
||||
stack: id,
|
||||
action: Types.StackWebhookAction.Deploy,
|
||||
})
|
||||
}
|
||||
loading={createPending}
|
||||
disabled={disabled || createPending}
|
||||
/>
|
||||
<ConfirmButton
|
||||
title="Enable Refresh"
|
||||
icon={<CirclePlus className="w-4 h-4" />}
|
||||
onClick={() =>
|
||||
createWebhook({
|
||||
stack: id,
|
||||
action: Types.StackWebhookAction.Refresh,
|
||||
})
|
||||
}
|
||||
loading={createPending}
|
||||
disabled={disabled || createPending}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</ConfigItem>
|
||||
);
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
environment: [
|
||||
{
|
||||
label: "Environment",
|
||||
|
||||
Reference in New Issue
Block a user