stack don't show Git Repo config is file contents defined in UI

This commit is contained in:
mbecker20
2024-08-18 16:15:22 -04:00
parent aae9bb9e51
commit 2f73461979

View File

@@ -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",