mirror of
https://github.com/moghtech/komodo.git
synced 2026-09-12 00:01:11 +00:00
implement owners management
This commit is contained in:
@@ -31,8 +31,8 @@ const Build: Component<{}> = (p) => {
|
||||
navigate("/");
|
||||
}
|
||||
});
|
||||
onCleanup(unsub);
|
||||
});
|
||||
onCleanup(() => unsub);
|
||||
return (
|
||||
<Show when={build()} fallback={<NotFound type="build" />}>
|
||||
<ActionStateProvider>
|
||||
|
||||
@@ -2,6 +2,7 @@ import {
|
||||
Component,
|
||||
createEffect,
|
||||
For,
|
||||
onCleanup,
|
||||
Show,
|
||||
} from "solid-js";
|
||||
import { useUpdates } from "../../state/hooks";
|
||||
@@ -25,6 +26,7 @@ const Updates: Component<{}> = (p) => {
|
||||
}
|
||||
});
|
||||
});
|
||||
onCleanup(() => unsub())
|
||||
return (
|
||||
<Show
|
||||
when={
|
||||
|
||||
@@ -1,111 +1,170 @@
|
||||
import { Component, createEffect, createSignal, For, Show } from "solid-js";
|
||||
import { pushNotification } from "../../..";
|
||||
import { useParams } from "@solidjs/router";
|
||||
import {
|
||||
Component,
|
||||
createEffect,
|
||||
createMemo,
|
||||
createSignal,
|
||||
For,
|
||||
onCleanup,
|
||||
Show,
|
||||
} from "solid-js";
|
||||
import { client } from "../../..";
|
||||
import { useAppState } from "../../../state/StateProvider";
|
||||
import { useUser } from "../../../state/UserProvider";
|
||||
import { User } from "../../../types";
|
||||
import { combineClasses } from "../../../util/helpers";
|
||||
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";
|
||||
|
||||
const PERMISSIONS_OPTIONS = [
|
||||
PermissionLevel.Read,
|
||||
PermissionLevel.Execute,
|
||||
PermissionLevel.Update,
|
||||
];
|
||||
|
||||
const Owners: Component<{}> = (p) => {
|
||||
// const { build } = useConfig();
|
||||
// const { user } = useUser();
|
||||
// const [userSearch, setUserSearch] = createSignal("");
|
||||
// const [users, setUsers] = createSignal<User[]>([]);
|
||||
// createEffect(() => {
|
||||
// if (userSearch().length > 0) {
|
||||
// getUsers(userSearch(), true).then((users) => {
|
||||
// setUsers(users.filter((user) => !build.owners.includes(user.username)));
|
||||
// });
|
||||
// } else {
|
||||
// setUsers([]);
|
||||
// }
|
||||
// });
|
||||
// return (
|
||||
// <Show when={build.loaded}>
|
||||
// <Grid class="config">
|
||||
// <Grid class="config-items scroller" style={{ height: "100%" }}>
|
||||
// <Grid
|
||||
// class={combineClasses("config-item shadow", themeClass())}
|
||||
// gap="0.5rem"
|
||||
// >
|
||||
// <Menu
|
||||
// show={userSearch() ? true : false}
|
||||
// close={() => setUserSearch("")}
|
||||
// target={
|
||||
// <Input
|
||||
// placeholder="add user"
|
||||
// value={userSearch()}
|
||||
// onEdit={setUserSearch}
|
||||
// style={{ width: "12rem" }}
|
||||
// />
|
||||
// }
|
||||
// content={
|
||||
// <>
|
||||
// <For each={users()}>
|
||||
// {(user) => (
|
||||
// <ConfirmButton
|
||||
// color="grey"
|
||||
// style={{
|
||||
// width: "100%",
|
||||
// "justify-content": "flex-start",
|
||||
// }}
|
||||
// onConfirm={async () => {
|
||||
// await addOwnerToBuild(build._id!, user.username);
|
||||
// pushNotification("good", "owner added to build");
|
||||
// setUserSearch("");
|
||||
// }}
|
||||
// confirm="add user"
|
||||
// >
|
||||
// {user.username}
|
||||
// </ConfirmButton>
|
||||
// )}
|
||||
// </For>
|
||||
// <Show when={users().length === 0}>no matching users</Show>
|
||||
// </>
|
||||
// }
|
||||
// menuStyle={{ width: "12rem" }}
|
||||
// />
|
||||
// <For each={build.owners}>
|
||||
// {(owner) => (
|
||||
// <Flex
|
||||
// alignItems="center"
|
||||
// justifyContent="space-between"
|
||||
// class={combineClasses("grey-no-hover", themeClass())}
|
||||
// style={{
|
||||
// padding: "0.5rem",
|
||||
// }}
|
||||
// >
|
||||
// <div class="big-text">
|
||||
// {owner}
|
||||
// {owner === username() && " ( you )"}
|
||||
// </div>
|
||||
// <Show when={permissions() > 1}>
|
||||
// <ConfirmButton
|
||||
// color="red"
|
||||
// onConfirm={async () => {
|
||||
// await removeOwnerFromBuild(build._id!, owner);
|
||||
// pushNotification(
|
||||
// "good",
|
||||
// "user removed from collaborators"
|
||||
// );
|
||||
// }}
|
||||
// >
|
||||
// remove
|
||||
// </ConfirmButton>
|
||||
// </Show>
|
||||
// </Flex>
|
||||
// )}
|
||||
// </For>
|
||||
// </Grid>
|
||||
// </Grid>
|
||||
// </Grid>
|
||||
// </Show>
|
||||
// );
|
||||
return <div></div>
|
||||
const { ws } = useAppState();
|
||||
const { build } = useConfig();
|
||||
const { user } = useUser();
|
||||
const params = useParams();
|
||||
const [userSearch, setUserSearch] = createSignal("");
|
||||
const [users, setUsers] = createSignal<User[]>([]);
|
||||
createEffect(() => {
|
||||
client.list_users().then(setUsers);
|
||||
});
|
||||
const getUser = (user_id: string) =>
|
||||
users().find((u) => getId(u) === user_id)!;
|
||||
const searchUsers = createMemo(() =>
|
||||
users().filter(
|
||||
(u) =>
|
||||
!u.admin &&
|
||||
u.enabled &&
|
||||
u.username.includes(userSearch()) &&
|
||||
(build.permissions[getId(u)] === undefined ||
|
||||
build.permissions[getId(u)] === PermissionLevel.None)
|
||||
)
|
||||
);
|
||||
let unsub = () => {};
|
||||
createEffect(() => {
|
||||
unsub();
|
||||
unsub = ws.subscribe(
|
||||
[Operation.ModifyUserPermissions, Operation.ModifyUserEnabled],
|
||||
() => {
|
||||
client.list_users().then(setUsers);
|
||||
}
|
||||
);
|
||||
});
|
||||
onCleanup(() => unsub());
|
||||
return (
|
||||
<Show when={build.loaded}>
|
||||
<Grid class="config">
|
||||
<Grid class="config-items scroller" style={{ height: "100%" }}>
|
||||
<Grid class={combineClasses("config-item shadow")} gap="0.5rem">
|
||||
<Menu
|
||||
show={userSearch() ? true : false}
|
||||
close={() => setUserSearch("")}
|
||||
target={
|
||||
<Input
|
||||
placeholder="add user"
|
||||
value={userSearch()}
|
||||
onEdit={setUserSearch}
|
||||
style={{ width: "12rem" }}
|
||||
/>
|
||||
}
|
||||
content={
|
||||
<>
|
||||
<For each={searchUsers()}>
|
||||
{(user) => (
|
||||
<ConfirmButton
|
||||
color="grey"
|
||||
style={{
|
||||
width: "100%",
|
||||
"justify-content": "flex-start",
|
||||
}}
|
||||
onConfirm={() => {
|
||||
client.update_user_permissions_on_target({
|
||||
user_id: getId(user),
|
||||
permission: PermissionLevel.Read,
|
||||
target_type: PermissionsTarget.Build,
|
||||
target_id: params.id,
|
||||
});
|
||||
setUserSearch("");
|
||||
}}
|
||||
confirm="add user"
|
||||
>
|
||||
{user.username}
|
||||
</ConfirmButton>
|
||||
)}
|
||||
</For>
|
||||
<Show when={users().length === 0}>no matching users</Show>
|
||||
</>
|
||||
}
|
||||
menuStyle={{ width: "12rem" }}
|
||||
/>
|
||||
<For each={Object.keys(build.permissions)}>
|
||||
{(user_id) => {
|
||||
const u = () => getUser(user_id);
|
||||
const permissions = () => build.permissions[user_id];
|
||||
return (
|
||||
<Flex
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
class={combineClasses("grey-no-hover")}
|
||||
style={{
|
||||
padding: "0.5rem",
|
||||
}}
|
||||
>
|
||||
<div class="big-text">
|
||||
{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
|
||||
color="red"
|
||||
onConfirm={() => {
|
||||
client.update_user_permissions_on_target({
|
||||
user_id,
|
||||
permission: PermissionLevel.None,
|
||||
target_type: PermissionsTarget.Build,
|
||||
target_id: params.id,
|
||||
});
|
||||
}}
|
||||
>
|
||||
remove
|
||||
</ConfirmButton>
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
}}
|
||||
</For>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Show>
|
||||
);
|
||||
};
|
||||
|
||||
export default Owners;
|
||||
|
||||
@@ -2,6 +2,7 @@ import { useParams } from "@solidjs/router";
|
||||
import {
|
||||
createContext,
|
||||
createEffect,
|
||||
onCleanup,
|
||||
ParentComponent,
|
||||
useContext,
|
||||
} from "solid-js";
|
||||
@@ -80,6 +81,8 @@ export const ConfigProvider: ParentComponent<{}> = (p) => {
|
||||
});
|
||||
});
|
||||
|
||||
onCleanup(() => update_unsub());
|
||||
|
||||
let modify_unsub = () => {};
|
||||
|
||||
createEffect(() => {
|
||||
@@ -95,6 +98,8 @@ export const ConfigProvider: ParentComponent<{}> = (p) => {
|
||||
);
|
||||
});
|
||||
|
||||
onCleanup(() => modify_unsub());
|
||||
|
||||
const userCanUpdate = () => user().admin || build.permissions[getId(user())] === PermissionLevel.Update;
|
||||
|
||||
const state = {
|
||||
|
||||
@@ -33,7 +33,7 @@ const BuildTabs: Component<{}> = (p) => {
|
||||
title: "build",
|
||||
element: () => <BuildConfig />,
|
||||
},
|
||||
userCanUpdate() && {
|
||||
user().admin && {
|
||||
title: "collaborators",
|
||||
element: () => <Owners />,
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, createEffect, For, Show } from "solid-js";
|
||||
import { Component, createEffect, For, onCleanup, Show } from "solid-js";
|
||||
import { useUpdates } from "../../state/hooks";
|
||||
import Grid from "../shared/layout/Grid";
|
||||
import Update from "../update/Update";
|
||||
@@ -26,6 +26,7 @@ const Updates: Component<{}> = (p) => {
|
||||
}
|
||||
});
|
||||
});
|
||||
onCleanup(() => unsub());
|
||||
return (
|
||||
<Show
|
||||
when={
|
||||
|
||||
@@ -19,13 +19,15 @@ import { OnClone, OnPull } from "./mount-repo/OnGit";
|
||||
import Loading from "../../../shared/loading/Loading";
|
||||
import Owners from "./Owners";
|
||||
import { pushNotification, URL } from "../../../..";
|
||||
import { combineClasses, copyToClipboard } from "../../../../util/helpers";
|
||||
import { combineClasses, copyToClipboard, getId } from "../../../../util/helpers";
|
||||
import { useAppDimensions } from "../../../../state/DimensionProvider";
|
||||
import { useUser } from "../../../../state/UserProvider";
|
||||
|
||||
const Config: Component<{}> = () => {
|
||||
const { deployment, reset, save, userCanUpdate } = useConfig();
|
||||
const { user } = useUser();
|
||||
const { isMobile } = useAppDimensions();
|
||||
const listenerUrl = () => `${URL}/api/listener/deployment/${deployment._id}`;
|
||||
const listenerUrl = () => `${URL}/api/listener/deployment/${getId(deployment)}`;
|
||||
return (
|
||||
<Show when={deployment.loaded}>
|
||||
<Grid class="config">
|
||||
@@ -97,7 +99,7 @@ const Config: Component<{}> = () => {
|
||||
</Grid>
|
||||
),
|
||||
},
|
||||
userCanUpdate() && {
|
||||
user().admin && {
|
||||
title: "collaborators",
|
||||
element: () => (
|
||||
<Grid
|
||||
|
||||
@@ -1,101 +1,170 @@
|
||||
import { Component, createEffect, createSignal, For, Show } from "solid-js";
|
||||
import { pushNotification } from "../../../..";
|
||||
import { useParams } from "@solidjs/router";
|
||||
import {
|
||||
Component,
|
||||
createEffect,
|
||||
createMemo,
|
||||
createSignal,
|
||||
For,
|
||||
onCleanup,
|
||||
Show,
|
||||
} from "solid-js";
|
||||
import { client } from "../../../..";
|
||||
import { useAppState } from "../../../../state/StateProvider";
|
||||
import { useUser } from "../../../../state/UserProvider";
|
||||
import { User } from "../../../../types";
|
||||
import { combineClasses } from "../../../../util/helpers";
|
||||
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";
|
||||
|
||||
const PERMISSIONS_OPTIONS = [
|
||||
PermissionLevel.Read,
|
||||
PermissionLevel.Execute,
|
||||
PermissionLevel.Update,
|
||||
];
|
||||
|
||||
const Owners: Component<{}> = (p) => {
|
||||
// const { deployment } = useConfig();
|
||||
// const { user } = useUser();
|
||||
// const [userSearch, setUserSearch] = createSignal("");
|
||||
// const [users, setUsers] = createSignal<User[]>([]);
|
||||
// createEffect(() => {
|
||||
// if (userSearch().length > 0) {
|
||||
// getUsers(userSearch(), true).then((users) => {
|
||||
// setUsers(
|
||||
// users.filter((user) => !deployment.owners.includes(user.username))
|
||||
// );
|
||||
// });
|
||||
// } else {
|
||||
// setUsers([]);
|
||||
// }
|
||||
// });
|
||||
// return (
|
||||
// <Grid
|
||||
// class={combineClasses("config-item shadow", themeClass())}
|
||||
// gap="0.5rem"
|
||||
// >
|
||||
// <Menu
|
||||
// show={userSearch() ? true : false}
|
||||
// close={() => setUserSearch("")}
|
||||
// target={
|
||||
// <Input
|
||||
// placeholder="add user"
|
||||
// value={userSearch()}
|
||||
// onEdit={setUserSearch}
|
||||
// style={{ width: "12rem" }}
|
||||
// />
|
||||
// }
|
||||
// content={
|
||||
// <>
|
||||
// <For each={users()}>
|
||||
// {(user) => (
|
||||
// <ConfirmButton
|
||||
// color="grey"
|
||||
// style={{ width: "100%", "justify-content": "flex-start" }}
|
||||
// onConfirm={async () => {
|
||||
// await addOwnerToDeployment(deployment._id!, user.username);
|
||||
// pushNotification("good", "owner added to deployment");
|
||||
// setUserSearch("");
|
||||
// }}
|
||||
// confirm="add user"
|
||||
// >
|
||||
// {user.username}
|
||||
// </ConfirmButton>
|
||||
// )}
|
||||
// </For>
|
||||
// <Show when={users().length === 0}>no matching users</Show>
|
||||
// </>
|
||||
// }
|
||||
// menuStyle={{ width: "12rem" }}
|
||||
// />
|
||||
// <For each={deployment.owners}>
|
||||
// {(owner) => (
|
||||
// <Flex
|
||||
// alignItems="center"
|
||||
// justifyContent="space-between"
|
||||
// class={combineClasses("grey-no-hover", themeClass())}
|
||||
// style={{
|
||||
// padding: "0.5rem",
|
||||
// }}
|
||||
// >
|
||||
// <div class="big-text">
|
||||
// {owner}
|
||||
// {owner === username() && " ( you )"}
|
||||
// </div>
|
||||
// <Show when={permissions() > 1}>
|
||||
// <ConfirmButton
|
||||
// color="red"
|
||||
// onConfirm={async () => {
|
||||
// await removeOwnerFromDeployment(deployment._id!, owner);
|
||||
// pushNotification("good", "user removed from collaborators");
|
||||
// }}
|
||||
// >
|
||||
// remove
|
||||
// </ConfirmButton>
|
||||
// </Show>
|
||||
// </Flex>
|
||||
// )}
|
||||
// </For>
|
||||
// </Grid>
|
||||
// );
|
||||
return <div></div>
|
||||
const { ws } = useAppState();
|
||||
const { deployment } = useConfig();
|
||||
const { user } = useUser();
|
||||
const params = useParams();
|
||||
const [userSearch, setUserSearch] = createSignal("");
|
||||
const [users, setUsers] = createSignal<User[]>([]);
|
||||
createEffect(() => {
|
||||
client.list_users().then(setUsers);
|
||||
});
|
||||
const getUser = (user_id: string) =>
|
||||
users().find((u) => getId(u) === user_id)!;
|
||||
const searchUsers = createMemo(() =>
|
||||
users().filter(
|
||||
(u) =>
|
||||
!u.admin &&
|
||||
u.enabled &&
|
||||
u.username.includes(userSearch()) &&
|
||||
(deployment.permissions![getId(u)] === undefined ||
|
||||
deployment.permissions![getId(u)] === PermissionLevel.None)
|
||||
)
|
||||
);
|
||||
let unsub = () => {};
|
||||
createEffect(() => {
|
||||
unsub();
|
||||
unsub = ws.subscribe(
|
||||
[Operation.ModifyUserPermissions, Operation.ModifyUserEnabled],
|
||||
() => {
|
||||
client.list_users().then(setUsers);
|
||||
}
|
||||
);
|
||||
});
|
||||
onCleanup(() => unsub());
|
||||
return (
|
||||
<Show when={deployment.loaded}>
|
||||
<Grid class="config">
|
||||
<Grid class="config-items scroller" style={{ height: "100%" }}>
|
||||
<Grid class={combineClasses("config-item shadow")} gap="0.5rem">
|
||||
<Menu
|
||||
show={userSearch() ? true : false}
|
||||
close={() => setUserSearch("")}
|
||||
target={
|
||||
<Input
|
||||
placeholder="add user"
|
||||
value={userSearch()}
|
||||
onEdit={setUserSearch}
|
||||
style={{ width: "12rem" }}
|
||||
/>
|
||||
}
|
||||
content={
|
||||
<>
|
||||
<For each={searchUsers()}>
|
||||
{(user) => (
|
||||
<ConfirmButton
|
||||
color="grey"
|
||||
style={{
|
||||
width: "100%",
|
||||
"justify-content": "flex-start",
|
||||
}}
|
||||
onConfirm={() => {
|
||||
client.update_user_permissions_on_target({
|
||||
user_id: getId(user),
|
||||
permission: PermissionLevel.Read,
|
||||
target_type: PermissionsTarget.Deployment,
|
||||
target_id: params.id,
|
||||
});
|
||||
setUserSearch("");
|
||||
}}
|
||||
confirm="add user"
|
||||
>
|
||||
{user.username}
|
||||
</ConfirmButton>
|
||||
)}
|
||||
</For>
|
||||
<Show when={users().length === 0}>no matching users</Show>
|
||||
</>
|
||||
}
|
||||
menuStyle={{ width: "12rem" }}
|
||||
/>
|
||||
<For each={Object.keys(deployment.permissions!)}>
|
||||
{(user_id) => {
|
||||
const u = () => getUser(user_id);
|
||||
const permissions = () => deployment.permissions![user_id];
|
||||
return (
|
||||
<Flex
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
class={combineClasses("grey-no-hover")}
|
||||
style={{
|
||||
padding: "0.5rem",
|
||||
}}
|
||||
>
|
||||
<div class="big-text">
|
||||
{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.Deployment,
|
||||
target_id: params.id,
|
||||
});
|
||||
}}
|
||||
position="bottom right"
|
||||
/>
|
||||
<ConfirmButton
|
||||
color="red"
|
||||
onConfirm={() => {
|
||||
client.update_user_permissions_on_target({
|
||||
user_id,
|
||||
permission: PermissionLevel.None,
|
||||
target_type: PermissionsTarget.Deployment,
|
||||
target_id: params.id,
|
||||
});
|
||||
}}
|
||||
>
|
||||
remove
|
||||
</ConfirmButton>
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
}}
|
||||
</For>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Show>
|
||||
);
|
||||
};
|
||||
|
||||
export default Owners;
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
createContext,
|
||||
createEffect,
|
||||
createSignal,
|
||||
onCleanup,
|
||||
ParentComponent,
|
||||
useContext,
|
||||
} from "solid-js";
|
||||
@@ -108,6 +109,8 @@ export const ConfigProvider: ParentComponent<{}> = (p) => {
|
||||
});
|
||||
});
|
||||
|
||||
onCleanup(() => update_unsub());
|
||||
|
||||
let modify_unsub = () => {};
|
||||
|
||||
createEffect(() => {
|
||||
@@ -123,6 +126,8 @@ export const ConfigProvider: ParentComponent<{}> = (p) => {
|
||||
);
|
||||
});
|
||||
|
||||
onCleanup(() => modify_unsub());
|
||||
|
||||
const userCanUpdate = () =>
|
||||
user().admin ||
|
||||
deployment.permissions![getId(user())] === PermissionLevel.Update;
|
||||
|
||||
@@ -2,6 +2,7 @@ import {
|
||||
Component,
|
||||
createEffect,
|
||||
For,
|
||||
onCleanup,
|
||||
Show,
|
||||
} from "solid-js";
|
||||
import { useUpdates } from "../../state/hooks";
|
||||
@@ -24,6 +25,7 @@ const Updates: Component<{}> = (p) => {
|
||||
}
|
||||
});
|
||||
});
|
||||
onCleanup(() => unsub());
|
||||
return (
|
||||
<Show when={updates.loaded() && (updates.collection()?.length || 0) > 0}>
|
||||
<Grid class={combineClasses("card shadow")}>
|
||||
|
||||
@@ -1,40 +1,75 @@
|
||||
import { useParams } from "@solidjs/router";
|
||||
import { Component, createEffect, createSignal, For, Show } from "solid-js";
|
||||
import { client, pushNotification } from "../../..";
|
||||
import {
|
||||
Component,
|
||||
createEffect,
|
||||
createMemo,
|
||||
createSignal,
|
||||
For,
|
||||
onCleanup,
|
||||
Show,
|
||||
} from "solid-js";
|
||||
import { client } from "../../..";
|
||||
import { useAppState } from "../../../state/StateProvider";
|
||||
import { useUser } from "../../../state/UserProvider";
|
||||
import { PermissionLevel, PermissionsTarget, User } from "../../../types";
|
||||
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 "./config/Provider";
|
||||
|
||||
const PERMISSIONS_OPTIONS = [
|
||||
PermissionLevel.Read,
|
||||
PermissionLevel.Execute,
|
||||
PermissionLevel.Update,
|
||||
];
|
||||
|
||||
const Owners: Component<{}> = (p) => {
|
||||
const { ws } = useAppState();
|
||||
const { server } = useConfig();
|
||||
const { user } = useUser();
|
||||
const params = useParams();
|
||||
const [userSearch, setUserSearch] = createSignal("");
|
||||
const [users, setUsers] = createSignal<User[]>([]);
|
||||
createEffect(() => {
|
||||
if (userSearch().length > 0) {
|
||||
// getUsers(userSearch(), true).then((users) => {
|
||||
// setUsers(
|
||||
// users.filter((user) => !server.owners.includes(user.username))
|
||||
// );
|
||||
// });
|
||||
} else {
|
||||
setUsers([]);
|
||||
}
|
||||
client.list_users().then(setUsers);
|
||||
});
|
||||
const getUser = (user_id: string) =>
|
||||
users().find((u) => getId(u) === user_id)!;
|
||||
const searchUsers = createMemo(() =>
|
||||
users().filter(
|
||||
(u) =>
|
||||
!u.admin &&
|
||||
u.enabled &&
|
||||
u.username.includes(userSearch()) &&
|
||||
(server.permissions![getId(u)] === undefined ||
|
||||
server.permissions![getId(u)] === PermissionLevel.None)
|
||||
)
|
||||
);
|
||||
let unsub = () => {};
|
||||
createEffect(() => {
|
||||
unsub();
|
||||
unsub = ws.subscribe(
|
||||
[Operation.ModifyUserPermissions, Operation.ModifyUserEnabled],
|
||||
() => {
|
||||
client.list_users().then(setUsers);
|
||||
}
|
||||
);
|
||||
});
|
||||
onCleanup(() => unsub());
|
||||
return (
|
||||
<Show when={server.loaded}>
|
||||
<Grid class="config">
|
||||
<Grid class="config-items scroller" style={{ height: "100%" }}>
|
||||
<Grid
|
||||
class={combineClasses("config-item shadow")}
|
||||
gap="0.5rem"
|
||||
>
|
||||
<Grid class={combineClasses("config-item shadow")} gap="0.5rem">
|
||||
<Menu
|
||||
show={userSearch() ? true : false}
|
||||
close={() => setUserSearch("")}
|
||||
@@ -48,7 +83,7 @@ const Owners: Component<{}> = (p) => {
|
||||
}
|
||||
content={
|
||||
<>
|
||||
<For each={users()}>
|
||||
<For each={searchUsers()}>
|
||||
{(user) => (
|
||||
<ConfirmButton
|
||||
color="grey"
|
||||
@@ -56,9 +91,13 @@ const Owners: Component<{}> = (p) => {
|
||||
width: "100%",
|
||||
"justify-content": "flex-start",
|
||||
}}
|
||||
onConfirm={async () => {
|
||||
await client.update_user_permissions_on_target({ user_id: getId(user), permission: PermissionLevel.Read, target_type: PermissionsTarget.Server, target_id: params.id });
|
||||
pushNotification("good", "owner added to server");
|
||||
onConfirm={() => {
|
||||
client.update_user_permissions_on_target({
|
||||
user_id: getId(user),
|
||||
permission: PermissionLevel.Read,
|
||||
target_type: PermissionsTarget.Server,
|
||||
target_id: params.id,
|
||||
});
|
||||
setUserSearch("");
|
||||
}}
|
||||
confirm="add user"
|
||||
@@ -72,37 +111,55 @@ const Owners: Component<{}> = (p) => {
|
||||
}
|
||||
menuStyle={{ width: "12rem" }}
|
||||
/>
|
||||
{/* <For each={Object.keys(server.permissions!)}>
|
||||
{(user_id) => (
|
||||
<Flex
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
class={combineClasses("grey-no-hover")}
|
||||
style={{
|
||||
padding: "0.5rem",
|
||||
}}
|
||||
>
|
||||
<div class="big-text">
|
||||
{owner}
|
||||
{owner === username() && " ( you )"}
|
||||
</div>
|
||||
<Show when={permissions() > 1}>
|
||||
<ConfirmButton
|
||||
color="red"
|
||||
onConfirm={async () => {
|
||||
await removeOwnerFromServer(server._id!, owner);
|
||||
pushNotification(
|
||||
"good",
|
||||
"user removed from collaborators"
|
||||
);
|
||||
}}
|
||||
>
|
||||
remove
|
||||
</ConfirmButton>
|
||||
</Show>
|
||||
</Flex>
|
||||
)}
|
||||
</For> */}
|
||||
<For each={Object.keys(server.permissions!)}>
|
||||
{(user_id) => {
|
||||
const u = () => getUser(user_id);
|
||||
const permissions = () => server.permissions![user_id];
|
||||
return (
|
||||
<Flex
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
class={combineClasses("grey-no-hover")}
|
||||
style={{
|
||||
padding: "0.5rem",
|
||||
}}
|
||||
>
|
||||
<div class="big-text">
|
||||
{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
|
||||
color="red"
|
||||
onConfirm={() => {
|
||||
client.update_user_permissions_on_target({
|
||||
user_id,
|
||||
permission: PermissionLevel.None,
|
||||
target_type: PermissionsTarget.Server,
|
||||
target_id: params.id,
|
||||
});
|
||||
}}
|
||||
>
|
||||
remove
|
||||
</ConfirmButton>
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
}}
|
||||
</For>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
@@ -2,8 +2,6 @@ import { useParams } from "@solidjs/router";
|
||||
import { Component, Show } from "solid-js";
|
||||
import { useAppState } from "../../../state/StateProvider";
|
||||
import { useUser } from "../../../state/UserProvider";
|
||||
import { PermissionLevel } from "../../../types";
|
||||
import { getId } from "../../../util/helpers";
|
||||
import Tabs, { Tab } from "../../shared/tabs/Tabs";
|
||||
import Config from "./config/Config";
|
||||
import { ConfigProvider } from "./config/Provider";
|
||||
@@ -15,9 +13,6 @@ const ServerTabs: Component<{}> = (p) => {
|
||||
const params = useParams();
|
||||
const { user } = useUser();
|
||||
const server = () => servers.get(params.id)!;
|
||||
const userCanUpdate = () =>
|
||||
user().admin ||
|
||||
server()!.server.permissions![getId(user())] === PermissionLevel.Update;
|
||||
return (
|
||||
<Show when={server()}>
|
||||
<ConfigProvider>
|
||||
@@ -33,7 +28,7 @@ const ServerTabs: Component<{}> = (p) => {
|
||||
title: "stats",
|
||||
element: () => <Stats />,
|
||||
},
|
||||
userCanUpdate() && {
|
||||
user().admin && {
|
||||
title: "collaborators",
|
||||
element: () => <Owners />,
|
||||
},
|
||||
|
||||
@@ -67,13 +67,16 @@ export const ConfigProvider: ParentComponent<{}> = (p) => {
|
||||
client.update_server(server);
|
||||
};
|
||||
|
||||
onCleanup(
|
||||
ws.subscribe([Operation.UpdateServer], (update) => {
|
||||
let unsub = () => {}
|
||||
createEffect(() => {
|
||||
unsub();
|
||||
unsub = ws.subscribe([Operation.UpdateServer], (update) => {
|
||||
if (update.target.id === params.id) {
|
||||
load();
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
onCleanup(() => unsub());
|
||||
|
||||
// onCleanup(
|
||||
// ws.subscribe(
|
||||
|
||||
Reference in New Issue
Block a user