mirror of
https://github.com/moghtech/komodo.git
synced 2026-08-21 16:01:12 +00:00
handle permissions
This commit is contained in:
+46
-39
@@ -32,9 +32,9 @@ const PERMISSIONS_OPTIONS = [
|
||||
PermissionLevel.Update,
|
||||
];
|
||||
|
||||
const Owners: Component<{}> = (p) => {
|
||||
const Permissions: Component<{}> = (p) => {
|
||||
const { ws } = useAppState();
|
||||
const { build } = useConfig();
|
||||
const { build, reset } = useConfig();
|
||||
const { user } = useUser();
|
||||
const params = useParams();
|
||||
const [userSearch, setUserSearch] = createSignal("");
|
||||
@@ -54,17 +54,22 @@ const Owners: Component<{}> = (p) => {
|
||||
build.permissions![getId(u)] === PermissionLevel.None)
|
||||
)
|
||||
);
|
||||
let unsub = () => {};
|
||||
let unsub_permissions = () => {};
|
||||
createEffect(() => {
|
||||
unsub();
|
||||
unsub = ws.subscribe(
|
||||
[Operation.ModifyUserPermissions, Operation.ModifyUserEnabled],
|
||||
() => {
|
||||
client.list_users().then(setUsers);
|
||||
}
|
||||
unsub_permissions();
|
||||
unsub_permissions = ws.subscribe([Operation.ModifyUserPermissions], () =>
|
||||
reset()
|
||||
);
|
||||
});
|
||||
onCleanup(() => unsub());
|
||||
onCleanup(() => unsub_permissions());
|
||||
let unsub_enabled = () => {};
|
||||
createEffect(() => {
|
||||
unsub_enabled();
|
||||
unsub_enabled = ws.subscribe([Operation.ModifyUserEnabled], () =>
|
||||
client.list_users().then(setUsers)
|
||||
);
|
||||
});
|
||||
onCleanup(() => unsub_enabled());
|
||||
return (
|
||||
<Show when={build.loaded}>
|
||||
<Grid class="config">
|
||||
@@ -137,34 +142,36 @@ const Owners: Component<{}> = (p) => {
|
||||
{u().username}
|
||||
{user_id === getId(user()) && " ( you )"}
|
||||
</div>
|
||||
<Flex alignItems="center">
|
||||
<Selector
|
||||
selected={permissions()}
|
||||
items={PERMISSIONS_OPTIONS}
|
||||
onSelect={(permission) => {
|
||||
client.update_user_permissions_on_target({
|
||||
user_id,
|
||||
permission: permission as PermissionLevel,
|
||||
target_type: PermissionsTarget.Build,
|
||||
target_id: params.id,
|
||||
});
|
||||
}}
|
||||
position="bottom right"
|
||||
/>
|
||||
<ConfirmButton
|
||||
class="red"
|
||||
onConfirm={() => {
|
||||
client.update_user_permissions_on_target({
|
||||
user_id,
|
||||
permission: PermissionLevel.None,
|
||||
target_type: PermissionsTarget.Build,
|
||||
target_id: params.id,
|
||||
});
|
||||
}}
|
||||
>
|
||||
remove
|
||||
</ConfirmButton>
|
||||
</Flex>
|
||||
<Show when={!u().admin && user_id !== getId(user())}>
|
||||
<Flex alignItems="center">
|
||||
<Selector
|
||||
selected={permissions()}
|
||||
items={PERMISSIONS_OPTIONS}
|
||||
onSelect={(permission) => {
|
||||
client.update_user_permissions_on_target({
|
||||
user_id,
|
||||
permission: permission as PermissionLevel,
|
||||
target_type: PermissionsTarget.Build,
|
||||
target_id: params.id,
|
||||
});
|
||||
}}
|
||||
position="bottom right"
|
||||
/>
|
||||
<ConfirmButton
|
||||
class="red"
|
||||
onConfirm={() => {
|
||||
client.update_user_permissions_on_target({
|
||||
user_id,
|
||||
permission: PermissionLevel.None,
|
||||
target_type: PermissionsTarget.Build,
|
||||
target_id: params.id,
|
||||
});
|
||||
}}
|
||||
>
|
||||
remove
|
||||
</ConfirmButton>
|
||||
</Flex>
|
||||
</Show>
|
||||
</Flex>
|
||||
</Show>
|
||||
);
|
||||
@@ -177,4 +184,4 @@ const Owners: Component<{}> = (p) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default Owners;
|
||||
export default Permissions;
|
||||
@@ -8,7 +8,7 @@ import SimpleTabs from "../../shared/tabs/SimpleTabs";
|
||||
import { Tab } from "../../shared/tabs/Tabs";
|
||||
import BuildConfig from "./build-config/BuildConfig";
|
||||
import GitConfig from "./git-config/GitConfig";
|
||||
import Owners from "./Owners";
|
||||
import Owners from "./Permissions";
|
||||
import { ConfigProvider } from "./Provider";
|
||||
|
||||
const BuildTabs: Component<{}> = (p) => {
|
||||
|
||||
@@ -17,7 +17,7 @@ import Updates from "./Updates";
|
||||
|
||||
const Deployment2: Component<{}> = (p) => {
|
||||
const { servers, deployments } = useAppState();
|
||||
const { isSemiMobile, isMobile } = useAppDimensions();
|
||||
const { isSemiMobile } = useAppDimensions();
|
||||
const params = useParams();
|
||||
const deployment = () => deployments.get(params.id);
|
||||
const server = () =>
|
||||
@@ -42,7 +42,7 @@ const Deployment2: Component<{}> = (p) => {
|
||||
<Header />
|
||||
<Actions />
|
||||
</Grid>
|
||||
<Show when={!isMobile()}>
|
||||
<Show when={!isSemiMobile()}>
|
||||
<Updates />
|
||||
</Show>
|
||||
</Grid>
|
||||
|
||||
@@ -38,11 +38,11 @@ const Header: Component<{}> = (p) => {
|
||||
class={combineClasses("card shadow")}
|
||||
style={{
|
||||
position: "relative",
|
||||
cursor: isSemiMobile() && userCanUpdate() ? "pointer" : undefined,
|
||||
cursor: isSemiMobile() ? "pointer" : undefined,
|
||||
height: "fit-content",
|
||||
}}
|
||||
onClick={() => {
|
||||
if (isSemiMobile() && userCanUpdate()) toggleShowUpdates();
|
||||
if (isSemiMobile()) toggleShowUpdates();
|
||||
}}
|
||||
>
|
||||
<Flex alignItems="center" justifyContent="space-between">
|
||||
|
||||
+26
-21
@@ -8,23 +8,23 @@ import {
|
||||
onCleanup,
|
||||
Show,
|
||||
} from "solid-js";
|
||||
import { client } from "../../../..";
|
||||
import { useAppState } from "../../../../state/StateProvider";
|
||||
import { useUser } from "../../../../state/UserProvider";
|
||||
import { client } from "../../..";
|
||||
import { useAppState } from "../../../state/StateProvider";
|
||||
import { useUser } from "../../../state/UserProvider";
|
||||
import {
|
||||
Operation,
|
||||
PermissionLevel,
|
||||
PermissionsTarget,
|
||||
User,
|
||||
} from "../../../../types";
|
||||
import { combineClasses, getId } from "../../../../util/helpers";
|
||||
import ConfirmButton from "../../../shared/ConfirmButton";
|
||||
import Input from "../../../shared/Input";
|
||||
import Flex from "../../../shared/layout/Flex";
|
||||
import Grid from "../../../shared/layout/Grid";
|
||||
import Menu from "../../../shared/menu/Menu";
|
||||
import Selector from "../../../shared/menu/Selector";
|
||||
import { useConfig } from "./Provider";
|
||||
} from "../../../types";
|
||||
import { combineClasses, getId } from "../../../util/helpers";
|
||||
import ConfirmButton from "../../shared/ConfirmButton";
|
||||
import Input from "../../shared/Input";
|
||||
import Flex from "../../shared/layout/Flex";
|
||||
import Grid from "../../shared/layout/Grid";
|
||||
import Menu from "../../shared/menu/Menu";
|
||||
import Selector from "../../shared/menu/Selector";
|
||||
import { useConfig } from "./config/Provider";
|
||||
|
||||
const PERMISSIONS_OPTIONS = [
|
||||
PermissionLevel.Read,
|
||||
@@ -34,7 +34,7 @@ const PERMISSIONS_OPTIONS = [
|
||||
|
||||
const Permissions: Component<{}> = (p) => {
|
||||
const { ws } = useAppState();
|
||||
const { deployment } = useConfig();
|
||||
const { deployment, reset } = useConfig();
|
||||
const { user } = useUser();
|
||||
const params = useParams();
|
||||
const [userSearch, setUserSearch] = createSignal("");
|
||||
@@ -54,17 +54,22 @@ const Permissions: Component<{}> = (p) => {
|
||||
deployment.permissions![getId(u)] === PermissionLevel.None)
|
||||
)
|
||||
);
|
||||
let unsub = () => {};
|
||||
let unsub_permissions = () => {};
|
||||
createEffect(() => {
|
||||
unsub();
|
||||
unsub = ws.subscribe(
|
||||
[Operation.ModifyUserPermissions, Operation.ModifyUserEnabled],
|
||||
() => {
|
||||
client.list_users().then(setUsers);
|
||||
}
|
||||
unsub_permissions();
|
||||
unsub_permissions = ws.subscribe([Operation.ModifyUserPermissions], () =>
|
||||
reset()
|
||||
);
|
||||
});
|
||||
onCleanup(() => unsub());
|
||||
onCleanup(() => unsub_permissions());
|
||||
let unsub_enabled = () => {};
|
||||
createEffect(() => {
|
||||
unsub_enabled();
|
||||
unsub_enabled = ws.subscribe([Operation.ModifyUserEnabled], () =>
|
||||
client.list_users().then(setUsers)
|
||||
);
|
||||
});
|
||||
onCleanup(() => unsub_enabled());
|
||||
return (
|
||||
<Grid class="config">
|
||||
<Grid
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
import { client } from "../../..";
|
||||
import SimpleTabs from "../../shared/tabs/SimpleTabs";
|
||||
import { ConfigProvider } from "./config/Provider";
|
||||
import Permissions from "./config/Permissions";
|
||||
import Permissions from "./Permissions";
|
||||
import { useUser } from "../../../state/UserProvider";
|
||||
|
||||
const DeploymentTabs: Component<{}> = () => {
|
||||
|
||||
@@ -17,7 +17,7 @@ import { Tab } from "../../../shared/tabs/Tabs";
|
||||
import RepoMount from "./mount-repo/RepoMount";
|
||||
import { OnClone, OnPull } from "./mount-repo/OnGit";
|
||||
import Loading from "../../../shared/loading/Loading";
|
||||
import Permissions from "./Permissions";
|
||||
import Permissions from "../Permissions";
|
||||
import { pushNotification, URL } from "../../../..";
|
||||
import { combineClasses, copyToClipboard, getId } from "../../../../util/helpers";
|
||||
import { useAppDimensions } from "../../../../state/DimensionProvider";
|
||||
|
||||
@@ -1,26 +1,16 @@
|
||||
import { A } from "@solidjs/router";
|
||||
import { Component, Show } from "solid-js";
|
||||
import { useAppState } from "../../../state/StateProvider";
|
||||
import { useUser } from "../../../state/UserProvider";
|
||||
import { PermissionLevel } from "../../../types";
|
||||
import {
|
||||
combineClasses,
|
||||
getId,
|
||||
readableMonitorTimestamp,
|
||||
} from "../../../util/helpers";
|
||||
import Icon from "../../shared/Icon";
|
||||
import Flex from "../../shared/layout/Flex";
|
||||
import HoverMenu from "../../shared/menu/HoverMenu";
|
||||
import s from "../home.module.scss";
|
||||
|
||||
const Build: Component<{ id: string }> = (p) => {
|
||||
const { builds } = useAppState();
|
||||
const { user } = useUser();
|
||||
const build = () => builds.get(p.id)!;
|
||||
const permissionLevel = () => {
|
||||
const level = build().permissions![getId(user())];
|
||||
return level ? level : PermissionLevel.None;
|
||||
};
|
||||
const version = () => {
|
||||
return `v${build().version.major}.${build().version.minor}.${
|
||||
build().version.patch
|
||||
@@ -42,16 +32,6 @@ const Build: Component<{ id: string }> = (p) => {
|
||||
<A href={`/build/${p.id}`} class={combineClasses(s.DropdownItem)}>
|
||||
<h2>{build().name}</h2>
|
||||
<Flex>
|
||||
<Show
|
||||
when={!user().admin && permissionLevel() !== PermissionLevel.None}
|
||||
>
|
||||
<HoverMenu
|
||||
target={<Icon type="edit" style={{ padding: "0.25rem" }} />}
|
||||
content="you are a collaborator"
|
||||
padding="0.5rem"
|
||||
position="bottom right"
|
||||
/>
|
||||
</Show>
|
||||
<div>{version()}</div>
|
||||
<div style={{ opacity: 0.7 }}>{lastBuiltAt()}</div>
|
||||
</Flex>
|
||||
|
||||
@@ -1,23 +1,14 @@
|
||||
import { A } from "@solidjs/router";
|
||||
import { Component, Show } from "solid-js";
|
||||
import { useAppState } from "../../../state/StateProvider";
|
||||
import { useUser } from "../../../state/UserProvider";
|
||||
import { PermissionLevel } from "../../../types";
|
||||
import { combineClasses, deploymentStateClass, getId } from "../../../util/helpers";
|
||||
import Circle from "../../shared/Circle";
|
||||
import Icon from "../../shared/Icon";
|
||||
import Flex from "../../shared/layout/Flex";
|
||||
import HoverMenu from "../../shared/menu/HoverMenu";
|
||||
import s from "../home.module.scss";
|
||||
|
||||
const Deployment: Component<{ id: string }> = (p) => {
|
||||
const { deployments } = useAppState();
|
||||
const { user } = useUser();
|
||||
const deployment = () => deployments.get(p.id)!;
|
||||
const permissionLevel = () => {
|
||||
const level = deployment().deployment.permissions![getId(user())];
|
||||
return level ? level : PermissionLevel.None;
|
||||
};
|
||||
return (
|
||||
<Show when={deployment()}>
|
||||
<A
|
||||
@@ -28,18 +19,6 @@ const Deployment: Component<{ id: string }> = (p) => {
|
||||
>
|
||||
<h2>{deployment().deployment.name}</h2>
|
||||
<Flex alignItems="center">
|
||||
<Show
|
||||
when={
|
||||
!user().admin && permissionLevel() !== PermissionLevel.None
|
||||
}
|
||||
>
|
||||
<HoverMenu
|
||||
target={<Icon type="edit" style={{ padding: "0.25rem" }} />}
|
||||
content="you are a collaborator"
|
||||
padding="0.5rem"
|
||||
position="bottom center"
|
||||
/>
|
||||
</Show>
|
||||
<div style={{ opacity: 0.7 }}>{deployments.status(p.id)}</div>
|
||||
<Circle
|
||||
size={1}
|
||||
|
||||
+50
-40
@@ -32,9 +32,9 @@ const PERMISSIONS_OPTIONS = [
|
||||
PermissionLevel.Update,
|
||||
];
|
||||
|
||||
const Owners: Component<{}> = (p) => {
|
||||
const Permissions: Component<{}> = (p) => {
|
||||
const { ws } = useAppState();
|
||||
const { server } = useConfig();
|
||||
const { server, reset } = useConfig();
|
||||
const { user } = useUser();
|
||||
const params = useParams();
|
||||
const [userSearch, setUserSearch] = createSignal("");
|
||||
@@ -54,21 +54,29 @@ const Owners: Component<{}> = (p) => {
|
||||
server.permissions![getId(u)] === PermissionLevel.None)
|
||||
)
|
||||
);
|
||||
let unsub = () => {};
|
||||
let unsub_permissions = () => {};
|
||||
createEffect(() => {
|
||||
unsub();
|
||||
unsub = ws.subscribe(
|
||||
[Operation.ModifyUserPermissions, Operation.ModifyUserEnabled],
|
||||
() => {
|
||||
client.list_users().then(setUsers);
|
||||
}
|
||||
unsub_permissions();
|
||||
unsub_permissions = ws.subscribe([Operation.ModifyUserPermissions], () =>
|
||||
reset()
|
||||
);
|
||||
});
|
||||
onCleanup(() => unsub());
|
||||
onCleanup(() => unsub_permissions());
|
||||
let unsub_enabled = () => {};
|
||||
createEffect(() => {
|
||||
unsub_enabled();
|
||||
unsub_enabled = ws.subscribe([Operation.ModifyUserEnabled], () =>
|
||||
client.list_users().then(setUsers)
|
||||
);
|
||||
});
|
||||
onCleanup(() => unsub_enabled());
|
||||
return (
|
||||
<Show when={server.loaded}>
|
||||
<Grid class="config">
|
||||
<Grid class="config-items scroller" style={{ height: "100%", "min-height": "400px" }}>
|
||||
<Grid
|
||||
class="config-items scroller"
|
||||
style={{ height: "100%", "min-height": "400px" }}
|
||||
>
|
||||
<Grid class={combineClasses("config-item shadow")} gap="0.5rem">
|
||||
<Menu
|
||||
show={userSearch() ? true : false}
|
||||
@@ -134,34 +142,36 @@ const Owners: Component<{}> = (p) => {
|
||||
{u().username}
|
||||
{user_id === getId(user()) && " ( you )"}
|
||||
</div>
|
||||
<Flex alignItems="center">
|
||||
<Selector
|
||||
selected={permissions()}
|
||||
items={PERMISSIONS_OPTIONS}
|
||||
onSelect={(permission) => {
|
||||
client.update_user_permissions_on_target({
|
||||
user_id,
|
||||
permission: permission as PermissionLevel,
|
||||
target_type: PermissionsTarget.Server,
|
||||
target_id: params.id,
|
||||
});
|
||||
}}
|
||||
position="bottom right"
|
||||
/>
|
||||
<ConfirmButton
|
||||
class="red"
|
||||
onConfirm={() => {
|
||||
client.update_user_permissions_on_target({
|
||||
user_id,
|
||||
permission: PermissionLevel.None,
|
||||
target_type: PermissionsTarget.Server,
|
||||
target_id: params.id,
|
||||
});
|
||||
}}
|
||||
>
|
||||
remove
|
||||
</ConfirmButton>
|
||||
</Flex>
|
||||
<Show when={!u().admin && user_id !== getId(user())}>
|
||||
<Flex alignItems="center">
|
||||
<Selector
|
||||
selected={permissions()}
|
||||
items={PERMISSIONS_OPTIONS}
|
||||
onSelect={(permission) => {
|
||||
client.update_user_permissions_on_target({
|
||||
user_id,
|
||||
permission: permission as PermissionLevel,
|
||||
target_type: PermissionsTarget.Server,
|
||||
target_id: params.id,
|
||||
});
|
||||
}}
|
||||
position="bottom right"
|
||||
/>
|
||||
<ConfirmButton
|
||||
class="red"
|
||||
onConfirm={() => {
|
||||
client.update_user_permissions_on_target({
|
||||
user_id,
|
||||
permission: PermissionLevel.None,
|
||||
target_type: PermissionsTarget.Server,
|
||||
target_id: params.id,
|
||||
});
|
||||
}}
|
||||
>
|
||||
remove
|
||||
</ConfirmButton>
|
||||
</Flex>
|
||||
</Show>
|
||||
</Flex>
|
||||
</Show>
|
||||
);
|
||||
@@ -174,4 +184,4 @@ const Owners: Component<{}> = (p) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default Owners;
|
||||
export default Permissions;
|
||||
@@ -6,7 +6,7 @@ import SimpleTabs from "../../shared/tabs/SimpleTabs";
|
||||
import { Tab } from "../../shared/tabs/Tabs";
|
||||
import Config from "./config/Config";
|
||||
import { ConfigProvider } from "./config/Provider";
|
||||
import Owners from "./Owners";
|
||||
import Permissions from "./Permissions";
|
||||
|
||||
const ServerTabs: Component<{}> = (p) => {
|
||||
const { servers } = useAppState();
|
||||
@@ -18,7 +18,7 @@ const ServerTabs: Component<{}> = (p) => {
|
||||
<ConfigProvider>
|
||||
<SimpleTabs
|
||||
containerClass="card shadow"
|
||||
containerStyle={{ "width": "100%", "box-sizing": "border-box" }}
|
||||
containerStyle={{ width: "100%", "box-sizing": "border-box" }}
|
||||
tabs={
|
||||
[
|
||||
{
|
||||
@@ -26,8 +26,8 @@ const ServerTabs: Component<{}> = (p) => {
|
||||
element: () => <Config />,
|
||||
},
|
||||
user().admin && {
|
||||
title: "collaborators",
|
||||
element: () => <Owners />,
|
||||
title: "permissions",
|
||||
element: () => <Permissions />,
|
||||
},
|
||||
].filter((e) => e) as Tab[]
|
||||
}
|
||||
|
||||
@@ -5,17 +5,19 @@ import Flex from "../../../shared/layout/Flex";
|
||||
import { useConfig } from "./Provider";
|
||||
|
||||
const Address: Component<{}> = (p) => {
|
||||
const { server, setServer } = useConfig();
|
||||
const { server, setServer, userCanUpdate } = useConfig();
|
||||
return (
|
||||
<Flex
|
||||
class={combineClasses("config-item shadow")}
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
>
|
||||
<h1>address</h1>
|
||||
<Input
|
||||
value={server.address}
|
||||
placeholder="address"
|
||||
onEdit={(value) => setServer("address", value)}
|
||||
disabled={!userCanUpdate()}
|
||||
/>
|
||||
</Flex>
|
||||
);
|
||||
|
||||
@@ -7,7 +7,7 @@ import Grid from "../../../shared/layout/Grid";
|
||||
import { useConfig } from "./Provider";
|
||||
|
||||
const Alerts: Component<{}> = (p) => {
|
||||
const { server, setServer } = useConfig();
|
||||
const { server, setServer, userCanUpdate } = useConfig();
|
||||
const [alerts, setAlerts] = createStore({
|
||||
cpu: server.cpu_alert?.toString(),
|
||||
mem: server.mem_alert?.toString(),
|
||||
@@ -32,6 +32,7 @@ const Alerts: Component<{}> = (p) => {
|
||||
}
|
||||
}}
|
||||
style={{ width: "4rem" }}
|
||||
disabled={!userCanUpdate()}
|
||||
/>
|
||||
<div>%</div>
|
||||
</Flex>
|
||||
@@ -51,6 +52,7 @@ const Alerts: Component<{}> = (p) => {
|
||||
}
|
||||
}}
|
||||
style={{ width: "4rem" }}
|
||||
disabled={!userCanUpdate()}
|
||||
/>
|
||||
<div>%</div>
|
||||
</Flex>
|
||||
@@ -70,6 +72,7 @@ const Alerts: Component<{}> = (p) => {
|
||||
}
|
||||
}}
|
||||
style={{ width: "4rem" }}
|
||||
disabled={!userCanUpdate()}
|
||||
/>
|
||||
<div>%</div>
|
||||
</Flex>
|
||||
|
||||
@@ -19,7 +19,7 @@ const Config: Component<{}> = (p) => {
|
||||
<Grid class="config-items scroller">
|
||||
<Address />
|
||||
<Enabled />
|
||||
<Networks />
|
||||
{/* <Networks /> */}
|
||||
<Info />
|
||||
<Alerts />
|
||||
<ToNotify />
|
||||
|
||||
@@ -4,7 +4,7 @@ import Flex from "../../../shared/layout/Flex";
|
||||
import { useConfig } from "./Provider";
|
||||
|
||||
const Enabled: Component<{}> = (p) => {
|
||||
const { server, setServer } = useConfig();
|
||||
const { server, setServer, userCanUpdate } = useConfig();
|
||||
return (
|
||||
<Flex
|
||||
class={combineClasses("config-item shadow")}
|
||||
@@ -15,6 +15,7 @@ const Enabled: Component<{}> = (p) => {
|
||||
<button
|
||||
class={server.enabled ? "green" : "red"}
|
||||
onClick={() => setServer("enabled", !server.enabled)}
|
||||
disabled={!userCanUpdate()}
|
||||
>
|
||||
{server.enabled ? "yes" : "no"}
|
||||
</button>
|
||||
|
||||
@@ -6,7 +6,7 @@ import Grid from "../../../shared/layout/Grid";
|
||||
import { useConfig } from "./Provider";
|
||||
|
||||
const Info: Component<{}> = (p) => {
|
||||
const { server, setServer } = useConfig();
|
||||
const { server, setServer, userCanUpdate } = useConfig();
|
||||
return (
|
||||
<Grid class={combineClasses("config-item shadow")}>
|
||||
<h1>info</h1>
|
||||
@@ -15,6 +15,7 @@ const Info: Component<{}> = (p) => {
|
||||
<Input
|
||||
value={server.region}
|
||||
onEdit={(value) => setServer("region", value)}
|
||||
disabled={!userCanUpdate()}
|
||||
/>
|
||||
</Flex>
|
||||
{/* <Flex justifyContent="space-between" alignItems="center">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Component, createSignal, For } from "solid-js";
|
||||
import { pushNotification } from "../../../..";
|
||||
import { client, pushNotification } from "../../../..";
|
||||
import { useAppState } from "../../../../state/StateProvider";
|
||||
import ConfirmButton from "../../../shared/ConfirmButton";
|
||||
import Icon from "../../../shared/Icon";
|
||||
|
||||
@@ -7,17 +7,23 @@ import { useConfig } from "./Provider";
|
||||
import { combineClasses } from "../../../../util/helpers";
|
||||
|
||||
const ToNotify: Component<{}> = (p) => {
|
||||
const { server, setServer } = useConfig();
|
||||
const { server, setServer, userCanUpdate } = useConfig();
|
||||
return (
|
||||
<Grid class={combineClasses("config-item shadow")}>
|
||||
<Flex alignItems="center" justifyContent="space-between">
|
||||
<h1>notify</h1>
|
||||
<button
|
||||
class="green"
|
||||
onClick={() => setServer("to_notify", (toNotify) => toNotify ? [...toNotify, ""] : [""])}
|
||||
>
|
||||
<Icon type="plus" />
|
||||
</button>
|
||||
<Show when={userCanUpdate()}>
|
||||
<button
|
||||
class="green"
|
||||
onClick={() =>
|
||||
setServer("to_notify", (toNotify) =>
|
||||
toNotify ? [...toNotify, ""] : [""]
|
||||
)
|
||||
}
|
||||
>
|
||||
<Icon type="plus" />
|
||||
</button>
|
||||
</Show>
|
||||
</Flex>
|
||||
<For each={server.to_notify}>
|
||||
{(user, index) => (
|
||||
@@ -26,23 +32,26 @@ const ToNotify: Component<{}> = (p) => {
|
||||
placeholder="slack user id"
|
||||
value={user}
|
||||
onEdit={(user) => setServer("to_notify", index(), user)}
|
||||
disabled={!userCanUpdate()}
|
||||
/>
|
||||
<button
|
||||
class="red"
|
||||
onClick={() =>
|
||||
setServer("to_notify", (toNotify) =>
|
||||
toNotify!.filter((_, i) => i !== index())
|
||||
)
|
||||
}
|
||||
>
|
||||
<Icon type="trash" />
|
||||
</button>
|
||||
<Show when={userCanUpdate()}>
|
||||
<button
|
||||
class="red"
|
||||
onClick={() =>
|
||||
setServer("to_notify", (toNotify) =>
|
||||
toNotify!.filter((_, i) => i !== index())
|
||||
)
|
||||
}
|
||||
>
|
||||
<Icon type="trash" />
|
||||
</button>
|
||||
</Show>
|
||||
</Flex>
|
||||
)}
|
||||
</For>
|
||||
<Show when={server.to_notify?.length === 0}>
|
||||
<div>no slack users to notify</div>
|
||||
</Show>
|
||||
<Show when={server.to_notify?.length === 0}>
|
||||
<div>no slack users to notify</div>
|
||||
</Show>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -74,16 +74,16 @@ export const Search: Component<{}> = (p) => {
|
||||
|
||||
const SearchMenu: Component<{ close: () => void }> = (p) => {
|
||||
const { tab, input, search } = useSearchState();
|
||||
const { isMobile } = useAppDimensions();
|
||||
const { isSemiMobile } = useAppDimensions();
|
||||
let inputRef: HTMLInputElement | undefined;
|
||||
onMount(() => {
|
||||
if (isMobile()) {
|
||||
if (isSemiMobile()) {
|
||||
inputRef?.focus();
|
||||
}
|
||||
});
|
||||
return (
|
||||
<>
|
||||
<Show when={isMobile()}>
|
||||
<Show when={isSemiMobile()}>
|
||||
<Input
|
||||
ref={() => inputRef}
|
||||
class={s.SearchInput}
|
||||
@@ -91,13 +91,13 @@ const SearchMenu: Component<{ close: () => void }> = (p) => {
|
||||
value={search.value()}
|
||||
onEdit={input.onEdit}
|
||||
onKeyDown={input.onKeyDown(inputRef)}
|
||||
style={{ width: isMobile() ? "100%" : undefined }}
|
||||
style={{ width: isSemiMobile() ? "100%" : undefined }}
|
||||
/>
|
||||
</Show>
|
||||
<ControlledTabs
|
||||
selected={tab.selected}
|
||||
set={tab.set}
|
||||
containerStyle={{ width: isMobile() ? "100%" : "30rem", gap: "0.5rem" }}
|
||||
containerStyle={{ width: isSemiMobile() ? "100%" : "30rem", gap: "0.5rem" }}
|
||||
tabs={[
|
||||
{
|
||||
title: "deployments",
|
||||
|
||||
@@ -211,7 +211,7 @@ export function useCollection<T>(
|
||||
query: () => Promise<Collection<T>>,
|
||||
idPath: string[]
|
||||
) {
|
||||
const [collection, { mutate }] = createResource(query);
|
||||
const [collection, { mutate, refetch }] = createResource(query);
|
||||
const add = (item: T) => {
|
||||
mutate((collection: any) => ({
|
||||
...collection,
|
||||
@@ -225,10 +225,11 @@ export function useCollection<T>(
|
||||
mutate((collection: any) => filterOutFromObj(collection, [id]));
|
||||
};
|
||||
const update = (item: T) => {
|
||||
const id = getNestedEntry(item, idPath);
|
||||
mutate((collection: any) => ({
|
||||
...collection,
|
||||
[getNestedEntry(item, idPath)]: {
|
||||
...collection[getNestedEntry(item, idPath)],
|
||||
[id]: {
|
||||
...collection[id],
|
||||
...item,
|
||||
},
|
||||
}));
|
||||
@@ -259,5 +260,6 @@ export function useCollection<T>(
|
||||
loaded,
|
||||
filter,
|
||||
filterArray,
|
||||
refetch,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -183,6 +183,28 @@ async function handleMessage(
|
||||
procedures.update(procedure);
|
||||
}
|
||||
}
|
||||
|
||||
// permissions
|
||||
else if (update.operation === Operation.ModifyUserPermissions) {
|
||||
if (update.status === UpdateStatus.Complete) {
|
||||
if (update.target.type === "Build") {
|
||||
const build = await client.get_build(update.target.id);
|
||||
builds.update(build);
|
||||
} else if (update.target.type === "Deployment") {
|
||||
const deployment = await client.get_deployment(update.target.id);
|
||||
deployments.update(deployment);
|
||||
} else if (update.target.type === "Server") {
|
||||
const server = await client.get_server(update.target.id);
|
||||
servers.update(server);
|
||||
} else if (update.target.type === "Group") {
|
||||
const group = await client.get_group(update.target.id);
|
||||
groups.update(group);
|
||||
} else if (update.target.type === "Procedure") {
|
||||
const procedure = await client.get_procedure(update.target.id);
|
||||
procedures.update(procedure);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default connectToWs;
|
||||
|
||||
Reference in New Issue
Block a user