forked from github-starred/komodo
add can edit indicator in the sidebar + username in topbar
This commit is contained in:
@@ -32,37 +32,6 @@ async function getDeployments(app: FastifyInstance, serverID: string) {
|
||||
}
|
||||
|
||||
const deployments = fp((app: FastifyInstance, _: {}, done: () => void) => {
|
||||
// app.get(
|
||||
// "/api/deployments",
|
||||
// { onRequest: [app.auth, app.userEnabled] },
|
||||
// async (req, res) => {
|
||||
// // returns the periphery deployments on the given serverID
|
||||
// // returns the core deployments if no serverID is specified
|
||||
// const { serverID } = req.query as { serverID?: string };
|
||||
// const server = serverID ? await app.servers.findById(serverID) : app.core;
|
||||
// if (!server) {
|
||||
// res.status(400);
|
||||
// res.send();
|
||||
// return;
|
||||
// }
|
||||
// const deployments = await app.deployments.find(
|
||||
// { serverID: server._id },
|
||||
// "name containerName serverID owners repo"
|
||||
// );
|
||||
// const status = server.isCore
|
||||
// ? await deploymentStatusLocal(app)
|
||||
// : await getPeripheryContainers(server);
|
||||
// res.send(
|
||||
// intoCollection(
|
||||
// deployments.map((deployment) => ({
|
||||
// ...deployment,
|
||||
// status: status[deployment.containerName!] || "not deployed",
|
||||
// }))
|
||||
// )
|
||||
// );
|
||||
// }
|
||||
// );
|
||||
|
||||
app.get(
|
||||
"/api/deployments",
|
||||
{ onRequest: [app.auth, app.userEnabled] },
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 20 20" enable-background="new 0 0 20 20" xml:space="preserve">
|
||||
<g id="edit_2_">
|
||||
<g>
|
||||
<path fill="#fceade" fill-rule="evenodd" clip-rule="evenodd" d="M4.59,12.59l2.83,2.83l7.65-7.65l-2.83-2.83L4.59,12.59z M2,18l4.41-1.59
|
||||
l-2.81-2.79L2,18z M16,2c-0.55,0-1.05,0.22-1.41,0.59l-1.65,1.65l2.83,2.83l1.65-1.65C17.78,5.05,18,4.55,18,4C18,2.9,17.1,2,16,2
|
||||
z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 751 B |
@@ -47,8 +47,8 @@ const Home: Component<{}> = (p) => {
|
||||
<Show
|
||||
when={filteredDeploymentIds() && filteredDeploymentIds()!.length > 0}
|
||||
>
|
||||
<Grid class="card shadow">
|
||||
<h1>my deployments</h1>
|
||||
<Grid gap="0.5rem" class="card shadow">
|
||||
<h1 style={{ opacity: 0.5 }}>my deployments</h1>
|
||||
<For each={filteredDeploymentIds()}>
|
||||
{(id) => (
|
||||
<button
|
||||
@@ -71,7 +71,7 @@ const Home: Component<{}> = (p) => {
|
||||
|
||||
<Show when={filteredServerIds() && filteredServerIds()!.length > 0}>
|
||||
<Grid class="card shadow">
|
||||
<h1>my servers</h1>
|
||||
<h1 style={{ opacity: 0.5 }}>my servers</h1>
|
||||
<For each={filteredServerIds()}>
|
||||
{(id) => (
|
||||
<button
|
||||
@@ -103,7 +103,7 @@ const Home: Component<{}> = (p) => {
|
||||
|
||||
<Show when={filteredBuildIds() && filteredBuildIds()!.length > 0}>
|
||||
<Grid class="card shadow">
|
||||
<h1>my builds</h1>
|
||||
<h1 style={{ opacity: 0.5 }}>my builds</h1>
|
||||
<For each={filteredBuildIds()}>
|
||||
{(id) => (
|
||||
<button
|
||||
|
||||
@@ -1,21 +1,33 @@
|
||||
import { Component, Show } from "solid-js";
|
||||
import { useAppState } from "../../../state/StateProvider";
|
||||
import { useUser } from "../../../state/UserProvider";
|
||||
import { combineClasses } from "../../../util/helpers";
|
||||
import Icon from "../../util/Icon";
|
||||
import HoverMenu from "../../util/menu/HoverMenu";
|
||||
import s from "../sidebar.module.scss";
|
||||
|
||||
const Build: Component<{ id: string }> = (p) => {
|
||||
const { builds, selected } = useAppState();
|
||||
const { permissions, username } = useUser();
|
||||
const build = () => builds.get(p.id)!;
|
||||
return (
|
||||
<Show when={build()}>
|
||||
<button
|
||||
class={combineClasses(
|
||||
selected.id() === p.id && "selected",
|
||||
s.DropdownItem,
|
||||
s.DropdownItem
|
||||
)}
|
||||
onClick={() => selected.set(build()._id!, "build")}
|
||||
>
|
||||
<div>{build().name}</div>
|
||||
<Show when={permissions() === 1 && build().owners.includes(username())}>
|
||||
<HoverMenu
|
||||
target={<Icon type="edit" style={{ padding: "0.25rem" }} />}
|
||||
content="you are a collaborator"
|
||||
padding="0.5rem"
|
||||
position="bottom right"
|
||||
/>
|
||||
</Show>
|
||||
</button>
|
||||
</Show>
|
||||
);
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
import { ContainerStatus } from "@monitor/types";
|
||||
import { Component, Show } from "solid-js";
|
||||
import { useAppState } from "../../../state/StateProvider";
|
||||
import { useUser } from "../../../state/UserProvider";
|
||||
import { combineClasses, deploymentStatusClass } from "../../../util/helpers";
|
||||
import Icon from "../../util/Icon";
|
||||
import Flex from "../../util/layout/Flex";
|
||||
import HoverMenu from "../../util/menu/HoverMenu";
|
||||
import s from "../sidebar.module.scss";
|
||||
|
||||
const Deployment: Component<{ id: string }> = (p) => {
|
||||
const { deployments, selected } = useAppState();
|
||||
const deployment = () => deployments.get(p.id);
|
||||
const { permissions, username } = useUser();
|
||||
const deployment = () => deployments.get(p.id)!;
|
||||
const status = () => {
|
||||
if (!deployment() || deployment()!.status === "not deployed") {
|
||||
return "not deployed";
|
||||
@@ -24,7 +29,21 @@ const Deployment: Component<{ id: string }> = (p) => {
|
||||
onClick={() => selected.set(deployment()!._id!, "deployment")}
|
||||
>
|
||||
<div>{deployment()!.name}</div>
|
||||
<div class={deploymentStatusClass(status())}>{status()}</div>
|
||||
<Flex alignItems="center">
|
||||
<Show
|
||||
when={
|
||||
permissions() === 1 && deployment().owners.includes(username()!)
|
||||
}
|
||||
>
|
||||
<HoverMenu
|
||||
target={<Icon type="edit" style={{ padding: "0.25rem" }} />}
|
||||
content="you are a collaborator"
|
||||
padding="0.5rem"
|
||||
position="bottom center"
|
||||
/>
|
||||
</Show>
|
||||
<div class={deploymentStatusClass(status())}>{status()}</div>
|
||||
</Flex>
|
||||
</button>
|
||||
</Show>
|
||||
);
|
||||
|
||||
@@ -22,13 +22,6 @@ const Server: Component<{ id: string }> = (p) => {
|
||||
);
|
||||
});
|
||||
const [open, toggleOpen] = useLocalStorageToggle(p.id);
|
||||
// createEffect(() => {
|
||||
// if (server() && !server()!.isCore) {
|
||||
// getDeployments({ serverID: p.id }).then((more) =>
|
||||
// deployments.addMany(more)
|
||||
// );
|
||||
// }
|
||||
// });
|
||||
return (
|
||||
<Show when={server()}>
|
||||
<div class={combineClasses(s.Server, "shadow")}>
|
||||
@@ -42,7 +35,7 @@ const Server: Component<{ id: string }> = (p) => {
|
||||
>
|
||||
<Flex>
|
||||
<Icon type="chevron-down" width="1rem" />
|
||||
<h2>{server()?.name}</h2>
|
||||
<h2 style={{ opacity: 0.7 }}>{server()?.name}</h2>
|
||||
</Flex>
|
||||
<div
|
||||
class={server()?.status === "OK" ? "green" : "red"}
|
||||
|
||||
@@ -11,7 +11,6 @@ const Account: Component<{ close: () => void }> = (p) => {
|
||||
const { username, permissions } = useUser();
|
||||
return (
|
||||
<Grid class={s.Account} placeItems="center end">
|
||||
<div>{username()}</div>
|
||||
<div>permissions: {readablePermissions(permissions())}</div>
|
||||
<Show when={permissions() > 1}>
|
||||
<button
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Component, createSignal } from "solid-js";
|
||||
import { useAppState } from "../../state/StateProvider";
|
||||
import { useUser } from "../../state/UserProvider";
|
||||
import { combineClasses, inPx } from "../../util/helpers";
|
||||
import Icon from "../util/Icon";
|
||||
import Flex from "../util/layout/Flex";
|
||||
@@ -12,6 +13,7 @@ export const TOPBAR_HEIGHT = 40;
|
||||
|
||||
const Topbar: Component = () => {
|
||||
const { sidebar, selected } = useAppState();
|
||||
const { username } = useUser();
|
||||
const [menu, setMenu] = createSignal<"updates" | "account">();
|
||||
const close = () => setMenu(undefined);
|
||||
return (
|
||||
@@ -56,7 +58,8 @@ const Topbar: Component = () => {
|
||||
menu() === "account" ? setMenu(undefined) : setMenu("account")
|
||||
}
|
||||
>
|
||||
<Icon type="user" alt="account" width="1.5rem" />
|
||||
{username()}
|
||||
<Icon type="chevron-down" />
|
||||
</button>
|
||||
}
|
||||
content={<Account close={close} />}
|
||||
|
||||
@@ -33,7 +33,8 @@ export type IconType =
|
||||
| "refresh"
|
||||
| "cut"
|
||||
| "fullscreen"
|
||||
| "github";
|
||||
| "github"
|
||||
| "edit";
|
||||
|
||||
const Icon: Component<{
|
||||
type: IconType;
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
Show,
|
||||
} from "solid-js";
|
||||
import { combineClasses } from "../../../util/helpers";
|
||||
import Flex from "../layout/Flex";
|
||||
import { getPositionClass } from "./helpers";
|
||||
import { Position } from "./helpers";
|
||||
import s from "./menu.module.scss";
|
||||
@@ -17,7 +18,7 @@ const HoverMenu: Component<{
|
||||
position?: Position;
|
||||
padding?: string;
|
||||
contentStyle?: JSX.CSSProperties;
|
||||
|
||||
containerStyle?: JSX.CSSProperties;
|
||||
}> = (p) => {
|
||||
const [show, set] = createSignal(false);
|
||||
const [buffer, setBuffer] = createSignal(false);
|
||||
@@ -33,12 +34,14 @@ const HoverMenu: Component<{
|
||||
}
|
||||
});
|
||||
return (
|
||||
<div
|
||||
<Flex
|
||||
class={s.HoverMenuTarget}
|
||||
style={p.containerStyle}
|
||||
onMouseEnter={() => set(true)}
|
||||
onMouseLeave={() => set(false)}
|
||||
onTouchStart={() => set((show) => !show)}
|
||||
// onClick={(e) => e.stopPropagation()}
|
||||
alignItems="center"
|
||||
>
|
||||
{p.target}
|
||||
<Show when={buffer()}>
|
||||
@@ -60,7 +63,7 @@ const HoverMenu: Component<{
|
||||
{p.content}
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ export type UserState = {
|
||||
user: () => User;
|
||||
setUser: Setter<false | User | undefined>;
|
||||
logout: () => void;
|
||||
username: () => string | undefined;
|
||||
username: () => string;
|
||||
permissions: () => number;
|
||||
loginStatus: () =>
|
||||
| "LOGGED_IN_ENABLED"
|
||||
@@ -30,11 +30,7 @@ export const UserProvider: Component = (p) => {
|
||||
mutate(false);
|
||||
};
|
||||
const username = () => {
|
||||
if (user()) {
|
||||
return (user() as User).username;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
return (user() as User)?.username!;
|
||||
};
|
||||
const loginStatus = createMemo(() => {
|
||||
const _user = user();
|
||||
|
||||
Reference in New Issue
Block a user