config deployment mount repo

This commit is contained in:
mbecker20
2022-04-02 15:29:10 -07:00
parent 135674600b
commit 43e18f93be
16 changed files with 278 additions and 85 deletions
@@ -9,7 +9,7 @@ const CliBuild: Component<{}> = (p) => {
return (
<Grid class="config-item shadow">
<h1>cli build</h1>
<div>build with a custom command</div>
<div style={{ opacity: 0.7 }}>build with a custom command</div>
<Flex justifyContent="space-between" alignItems="center">
<div>build path</div>
<Input
@@ -4,42 +4,49 @@ import Input from "../../../util/Input";
import Grid from "../../../util/layout/Grid";
import { useConfig } from "../Provider";
import s from "../../build.module.css";
import Flex from "../../../util/layout/Flex";
const OnClone: Component = () => {
const { build, setBuild } = useConfig();
return (
<Grid class="config-item shadow">
<h1>on clone</h1>
<Input
placeholder="path relative to repo"
value={build.onClone?.path || ""}
onEdit={(path) => {
if (
path.length === 0 &&
(!build.onClone ||
!build.onClone.command ||
build.onClone.command.length === 0)
) {
setBuild("onClone", undefined);
}
setBuild("onClone", { path });
}}
/>
<Input
placeholder="command"
value={build.onClone?.command || ""}
onEdit={(command) => {
if (
command.length === 0 &&
(!build.onClone ||
!build.onClone.path ||
build.onClone.path.length === 0)
) {
setBuild("onClone", undefined);
}
setBuild("onClone", { command });
}}
/>
<Flex alignItems="center" justifyContent="space-between">
path:
<Input
placeholder="relative to repo"
value={build.onClone?.path || ""}
onEdit={(path) => {
if (
path.length === 0 &&
(!build.onClone ||
!build.onClone.command ||
build.onClone.command.length === 0)
) {
setBuild("onClone", undefined);
}
setBuild("onClone", { path });
}}
/>
</Flex>
<Flex alignItems="center" justifyContent="space-between">
command:
<Input
placeholder="command"
value={build.onClone?.command || ""}
onEdit={(command) => {
if (
command.length === 0 &&
(!build.onClone ||
!build.onClone.path ||
build.onClone.path.length === 0)
) {
setBuild("onClone", undefined);
}
setBuild("onClone", { command });
}}
/>
</Flex>
</Grid>
);
};
@@ -12,24 +12,47 @@ import ConfirmButton from "../../../util/ConfirmButton";
import Restart from "./Restart";
import DockerAccount from "./DockerAccount";
import Git from "./Git";
import Tabs from "../../../util/tabs/Tabs";
import RepoMount from "./RepoMount";
import { OnClone, OnPull } from "./OnGit";
const Config: Component<{}> = (p) => {
const { deployment, reset, save } = useConfig();
return (
<Show when={deployment.loaded}>
<Grid class="config">
<Grid class="config-items scroller">
<Image />
<Show when={deployment.image}>
<DockerAccount />
</Show>
<Network />
<Restart />
<Ports />
<Mounts />
<Env />
<Git />
</Grid>
<Tabs
tabsGap="0rem"
tabs={[
{
title: "container",
element: (
<Grid class="config-items scroller">
<Image />
<Show when={deployment.image}>
<DockerAccount />
</Show>
<Network />
<Restart />
<Ports />
<Mounts />
<Env />
</Grid>
),
},
{
title: "repo mount",
element: (
<Grid class="config-items scroller">
<Git />
<RepoMount />
<OnClone />
<OnPull />
</Grid>
),
},
]}
/>
<Show when={deployment.updated}>
<Flex style={{ "place-self": "center", padding: "1rem" }}>
<button onClick={reset}>
@@ -27,7 +27,7 @@ const Env: Component<{}> = (p) => {
>
<div>none</div>
</Show>
<button onClick={onAdd}>
<button class="green" onClick={onAdd}>
<Icon type="plus" />
</button>
</Flex>
@@ -56,7 +56,7 @@ const Env: Component<{}> = (p) => {
setDeployment("environment", index(), "value", value)
}
/>
<button onClick={() => onRemove(index())}>
<button class="red" onClick={() => onRemove(index())}>
<Icon type="minus" />
</button>
</Flex>
@@ -7,11 +7,20 @@ import Selector from "../../../util/menu/Selector";
import { useConfig } from "./Provider";
const Git: Component<{}> = (p) => {
const { githubAccounts } = useAppState();
const { deployment, setDeployment } = useConfig();
return (
const { githubAccounts } = useAppState();
const { deployment, setDeployment } = useConfig();
return (
<Grid class="config-item shadow">
<h1>deployment repo</h1>
{/* <Flex alignItems="center" justifyContent="space-between">
<h1>deployment repo</h1>
<Toggle
toggled={deployment.repo !== undefined}
onChange={(toggled) =>
setDeployment("repo", toggled ? "" : undefined)
}
/>
</Flex> */}
<h1>github config</h1>
<Flex justifyContent="space-between" alignItems="center">
<div>repo</div>
<Input
@@ -47,6 +56,6 @@ const Git: Component<{}> = (p) => {
</Show>
</Grid>
);
}
};
export default Git;
export default Git;
@@ -0,0 +1,95 @@
import { Component } from "solid-js";
import Input from "../../../util/Input";
import Flex from "../../../util/layout/Flex";
import Grid from "../../../util/layout/Grid";
import { useConfig } from "./Provider";
export const OnClone: Component<{}> = (p) => {
const { deployment, setDeployment } = useConfig();
return (
<Grid class="config-item shadow">
<h1>on clone</h1>
<Flex alignItems="center" justifyContent="space-between">
path:
<Input
placeholder="relative to repo"
value={deployment.onClone?.path || ""}
onEdit={(path) => {
if (
path.length === 0 &&
(!deployment.onClone ||
!deployment.onClone.command ||
deployment.onClone.command.length === 0)
) {
setDeployment("onClone", undefined);
}
setDeployment("onClone", { path });
}}
/>
</Flex>
<Flex alignItems="center" justifyContent="space-between">
command:
<Input
placeholder="command"
value={deployment.onClone?.command || ""}
onEdit={(command) => {
if (
command.length === 0 &&
(!deployment.onClone ||
!deployment.onClone.path ||
deployment.onClone.path.length === 0)
) {
setDeployment("onClone", undefined);
}
setDeployment("onClone", { command });
}}
/>
</Flex>
</Grid>
);
};
export const OnPull: Component<{}> = (p) => {
const { deployment, setDeployment } = useConfig();
return (
<Grid class="config-item shadow">
<h1>on pull</h1>
<Flex alignItems="center" justifyContent="space-between">
path:
<Input
placeholder="relative to repo"
value={deployment.onPull?.path || ""}
onEdit={(path) => {
if (
path.length === 0 &&
(!deployment.onPull ||
!deployment.onPull.command ||
deployment.onPull.command.length === 0)
) {
setDeployment("onPull", undefined);
}
setDeployment("onPull", { path });
}}
/>
</Flex>
<Flex alignItems="center" justifyContent="space-between">
command:
<Input
placeholder="command"
value={deployment.onPull?.command || ""}
onEdit={(command) => {
if (
command.length === 0 &&
(!deployment.onPull ||
!deployment.onPull.path ||
deployment.onPull.path.length === 0)
) {
setDeployment("onPull", undefined);
}
setDeployment("onPull", { command });
}}
/>
</Flex>
</Grid>
);
};
@@ -23,7 +23,7 @@ const Ports: Component<{}> = (p) => {
<Show when={!deployment.ports || deployment.ports.length === 0}>
<div>none</div>
</Show>
<button onClick={onAdd}>
<button class="green" onClick={onAdd}>
<Icon type="plus" />
</button>
</Flex>
@@ -47,7 +47,7 @@ const Ports: Component<{}> = (p) => {
setDeployment("ports", index(), "container", value)
}
/>
<button onClick={() => onRemove(index())}>
<button class="red" onClick={() => onRemove(index())}>
<Icon type="minus" />
</button>
</Flex>
@@ -0,0 +1,31 @@
import { Component } from "solid-js";
import Input from "../../../util/Input";
import Flex from "../../../util/layout/Flex";
import Grid from "../../../util/layout/Grid";
import { useConfig } from "./Provider";
const RepoMount: Component<{}> = (p) => {
const { deployment, setDeployment } = useConfig();
return (
<Grid class="config-item shadow">
<h1>mount</h1>
<Flex alignItems="center" justifyContent="space-between">
<Input
placeholder="repo folder to mount"
value={deployment.repoMount || ""}
style={{ width: "40%" }}
onEdit={(value) => setDeployment("repoMount", value)}
/>
{" : "}
<Input
placeholder="container mount point"
value={deployment.containerMount || ""}
style={{ width: "40%" }}
onEdit={(value) => setDeployment("containerMount", value)}
/>
</Flex>
</Grid>
);
};
export default RepoMount;
@@ -23,7 +23,7 @@ const Volumes: Component<{}> = (p) => {
<Show when={!deployment.volumes || deployment.volumes.length === 0}>
<div>none</div>
</Show>
<button onClick={onAdd}>
<button class="green" onClick={onAdd}>
<Icon type="plus" />
</button>
</Flex>
@@ -34,7 +34,7 @@ const Volumes: Component<{}> = (p) => {
placeholder="system"
value={local}
style={{ width: "40%" }}
onConfirm={(value) =>
onEdit={(value) =>
setDeployment("volumes", index(), "local", value)
}
/>
@@ -43,11 +43,11 @@ const Volumes: Component<{}> = (p) => {
placeholder="container"
value={container}
style={{ width: "40%" }}
onConfirm={(value) =>
onEdit={(value) =>
setDeployment("volumes", index(), "container", value)
}
/>
<button onClick={() => onRemove(index())}>
<button class="red" onClick={() => onRemove(index())}>
<Icon type="minus" />
</button>
</Flex>
+1
View File
@@ -32,6 +32,7 @@ const New: Component<{
placeholder={p.placeholder}
value={name()}
onEdit={setName}
onConfirm={create}
style={{ width: "11rem" }}
/>
<Flex gap="0.4rem">
+1 -2
View File
@@ -14,7 +14,7 @@ import s from "./sidebar.module.css";
const SIDEBAR_WIDTH = 350;
const Sidebar: Component<{}> = () => {
const { sidebar, servers } = useAppState();
const { sidebar, servers, selected } = useAppState();
const { height } = useAppDimensions();
const { permissions } = useUser();
return (
@@ -59,7 +59,6 @@ const Sidebar: Component<{}> = () => {
),
},
]}
localStorageKey="sidebar-tab"
/>
</Show>
);
+29 -9
View File
@@ -1,6 +1,13 @@
import { Component, createSignal, For, JSX, JSXElement } from "solid-js";
import {
Accessor,
Component,
createSignal,
For,
JSX,
JSXElement,
} from "solid-js";
import { combineClasses } from "../../../util/helpers";
import { useLocalStorage } from "../../../util/hooks";
import { LocalStorageSetter, useLocalStorage } from "../../../util/hooks";
import Flex from "../layout/Flex";
import s from "./Tabs.module.css";
@@ -16,7 +23,6 @@ const Tabs: Component<{
localStorageKey?: string;
tabsGap?: string;
tabStyle?: JSX.CSSProperties;
titleStyle?: JSX.CSSProperties;
containerClass?: string;
containerStyle?: JSX.CSSProperties;
}> = (p) => {
@@ -24,19 +30,33 @@ const Tabs: Component<{
const [selected, set] = p.localStorageKey
? useLocalStorage(def, p.localStorageKey)
: createSignal(def);
const current = () =>
p.tabs.filter((tab) => tab.title === selected())[0];
return <ControlledTabs selected={selected} set={set} {...p} />;
};
export const ControlledTabs: Component<{
tabs: Tab[];
selected: Accessor<string>;
set: LocalStorageSetter<string>;
tabsGap?: string;
tabStyle?: JSX.CSSProperties;
containerClass?: string;
containerStyle?: JSX.CSSProperties;
}> = (p) => {
const current = () => p.tabs.filter((tab) => tab.title === p.selected())[0];
const getClassName = (title: string) =>
selected() === title ? combineClasses(s.Tab, s.Active) : s.Tab;
p.selected() === title ? combineClasses(s.Tab, s.Active) : s.Tab;
return (
<div class={combineClasses(s.Tabs, p.containerClass)} style={p.containerStyle}>
<Flex gap={p.tabsGap} alignItems="center" justifyContent="space-evenly">
<div
class={combineClasses(s.Tabs, p.containerClass)}
style={p.containerStyle}
>
<Flex gap={p.tabsGap || "0rem"} alignItems="center" justifyContent="space-evenly">
<For each={p.tabs}>
{(tab) => (
<button
class={getClassName(tab.title)}
style={p.tabStyle}
onClick={() => set(tab.title)}
onClick={() => p.set(tab.title)}
>
{tab.titleElement || tab.title}
</button>
+17 -13
View File
@@ -1,5 +1,6 @@
import { Component, JSXElement } from "solid-js";
import Flex from "../layout/Flex";
import { toggleCss } from "./css";
const Toggle: Component<{
label?: JSXElement;
@@ -7,19 +8,22 @@ const Toggle: Component<{
onChange?: (toggled: boolean) => void;
}> = (p) => {
return (
<Flex alignItems="center" justifyContent="space-between">
{p.label}
<label class="switch">
<input
type="checkbox"
checked={p.toggled}
onInput={() => {
p.onChange && p.onChange(!p.toggled);
}}
/>
<span class="slider round"></span>
</label>
</Flex>
<>
<style>{toggleCss()}</style>
<Flex alignItems="center" justifyContent="space-between">
{p.label}
<label class="toggle">
<input
type="checkbox"
checked={p.toggled}
onInput={() => {
p.onChange && p.onChange(!p.toggled);
}}
/>
<span class="slider round"></span>
</label>
</Flex>
</>
);
};
@@ -3,6 +3,8 @@ export function toggleCss(scale = 0.75) {
.toggle {
position: relative;
display: inline-block;
padding: 0;
margin: 0;
width: ${60 * scale}px;
height: ${34 * scale}px;
}
+2 -2
View File
@@ -205,8 +205,8 @@ h1 {
}
.config-items {
max-height: 100%;
padding: 0.5rem;
max-height: 65vh;
padding: 0rem 0.5rem;
}
.config-item {
+4 -2
View File
@@ -33,13 +33,15 @@ export function useToggleTimeout(
return [s, toggle];
}
export type LocalStorageSetter<T> = (arg: T | ((s: T) => T)) => void;
export function useLocalStorageToggle(
key: string,
initial?: boolean
): [
Accessor<boolean>,
() => void,
(arg: boolean | ((arg: boolean) => boolean)) => void
LocalStorageSetter<boolean>
] {
const [s, set] = useLocalStorage(initial || false, key);
const toggle = () => set((s) => !s);
@@ -49,7 +51,7 @@ export function useLocalStorageToggle(
export function useLocalStorage<T>(
defaultStore: T,
key: string
): [Accessor<T>, (arg: T | ((s: T) => T)) => void] {
): [Accessor<T>, LocalStorageSetter<T>] {
const toStore = window.localStorage.getItem(key);
const [stored, setStored] = createSignal<T>(
toStore ? JSON.parse(toStore) : defaultStore