collapsable updates in mobile

This commit is contained in:
mbecker20
2022-04-23 04:06:50 -07:00
parent b1a4481688
commit 6d230a3efd
9 changed files with 222 additions and 98 deletions
+12
View File
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<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="chevron_up_1_">
<g>
<path fill="#fceade" fill-rule="evenodd" clip-rule="evenodd" d="M16.71,12.29l-6-6C10.53,6.11,10.28,6,10,6S9.47,6.11,9.29,6.29l-6,6
C3.11,12.47,3,12.72,3,13c0,0.55,0.45,1,1,1c0.28,0,0.53-0.11,0.71-0.29L10,8.41l5.29,5.29C15.47,13.89,15.72,14,16,14
c0.55,0,1-0.45,1-1C17,12.72,16.89,12.47,16.71,12.29z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 694 B

+5 -1
View File
@@ -1,4 +1,5 @@
import { Component, Show } from "solid-js";
import { useAppDimensions } from "../../state/DimensionProvider";
import { useAppState } from "../../state/StateProvider";
import { useTheme } from "../../state/ThemeProvider";
import { combineClasses } from "../../util/helpers";
@@ -14,6 +15,7 @@ const Build: Component<{}> = (p) => {
const { builds, selected } = useAppState();
const build = () => builds.get(selected.id())!;
const { themeClass } = useTheme();
const { isMobile } = useAppDimensions();
return (
<Show when={build()} fallback={<NotFound type="build" />}>
<ActionStateProvider>
@@ -22,7 +24,9 @@ const Build: Component<{}> = (p) => {
<Grid class="left-content">
<Header />
<Actions />
<Updates />
<Show when={!isMobile()}>
<Updates />
</Show>
</Grid>
{/* right / tabs */}
<BuildTabs />
+53 -26
View File
@@ -10,6 +10,9 @@ import Grid from "../util/layout/Grid";
import { useActionStates } from "./ActionStateProvider";
import { useTheme } from "../../state/ThemeProvider";
import { combineClasses } from "../../util/helpers";
import { useAppDimensions } from "../../state/DimensionProvider";
import Updates from "./Updates";
import { useLocalStorageToggle } from "../../util/hooks";
const Header: Component<{}> = (p) => {
const { builds, selected, ws } = useAppState();
@@ -17,36 +20,60 @@ const Header: Component<{}> = (p) => {
const actions = useActionStates();
const { permissions, username } = useUser();
const { themeClass } = useTheme();
const { isMobile } = useAppDimensions();
const [showUpdates, toggleShowUpdates] =
useLocalStorageToggle("show-updates");
return (
<Flex
class={combineClasses("card shadow", themeClass())}
justifyContent="space-between"
alignItems="center"
>
<Grid gap="0.1rem">
<h1>{build().name}</h1>
<div style={{ opacity: 0.8 }}>{getSub(build())}</div>
</Grid>
<Show when={permissions() >= 2 || build().owners.includes(username()!)}>
<Show
when={!actions.deleting}
fallback={
<button class="red">
<Icon type="trash" />
</button>
}
>
<ConfirmButton
onConfirm={() => {
ws.send(DELETE_BUILD, { buildID: selected.id() });
}}
color="red"
<>
<Flex
class={combineClasses("card shadow", themeClass())}
justifyContent="space-between"
alignItems="center"
style={{
position: "relative",
cursor: isMobile() ? "pointer" : undefined,
}}
onClick={() => {
if (isMobile()) toggleShowUpdates();
}}
>
<Grid gap="0.1rem">
<h1>{build().name}</h1>
<div style={{ opacity: 0.8 }}>{getSub(build())}</div>
</Grid>
<Show when={permissions() >= 2 || build().owners.includes(username()!)}>
<Show
when={!actions.deleting}
fallback={
<button class="red">
<Icon type="trash" />
</button>
}
>
<Icon type="trash" />
</ConfirmButton>
<ConfirmButton
onConfirm={() => {
ws.send(DELETE_BUILD, { buildID: selected.id() });
}}
color="red"
>
<Icon type="trash" />
</ConfirmButton>
</Show>
</Show>
<Show when={isMobile()}>
<Flex gap="0.5rem" alignItems="center" class="show-updates-indicator">
updates{" "}
<Icon
type={showUpdates() ? "chevron-up" : "chevron-down"}
width="0.9rem"
/>
</Flex>
</Show>
</Flex>
<Show when={isMobile() && showUpdates()}>
<Updates />
</Show>
</Flex>
</>
);
};
@@ -1,4 +1,5 @@
import { Component, Show } from "solid-js";
import { useAppDimensions } from "../../state/DimensionProvider";
import { useAppState } from "../../state/StateProvider";
import { useTheme } from "../../state/ThemeProvider";
import { combineClasses } from "../../util/helpers";
@@ -16,6 +17,7 @@ const Deployment: Component<{}> = (p) => {
const deployment = () => deployments.get(selected.id()!);
const server = () => deployment() && servers.get(deployment()?.serverID!);
const { themeClass } = useTheme();
const { isMobile } = useAppDimensions();
return (
<Show
when={deployment() && server()}
@@ -27,7 +29,9 @@ const Deployment: Component<{}> = (p) => {
<Grid class="left-content">
<Header />
<Actions />
<Updates />
<Show when={!isMobile()}>
<Updates />
</Show>
</Grid>
{/* right / tabs */}
<DeploymentTabs />
+78 -44
View File
@@ -16,6 +16,9 @@ import HoverMenu from "../util/menu/HoverMenu";
import { useActionStates } from "./ActionStateProvider";
import { useTheme } from "../../state/ThemeProvider";
import Button from "../util/Button";
import { useLocalStorageToggle } from "../../util/hooks";
import { useAppDimensions } from "../../state/DimensionProvider";
import Updates from "./Updates";
const Header: Component<{ exiting?: boolean }> = (p) => {
const { deployments, ws, selected } = useAppState();
@@ -33,57 +36,88 @@ const Header: Component<{ exiting?: boolean }> = (p) => {
: (deployment()!.status as ContainerStatus).Status.toLowerCase();
const actions = useActionStates();
const { themeClass } = useTheme();
const { isMobile } = useAppDimensions();
const [showUpdates, toggleShowUpdates] =
useLocalStorageToggle("show-updates");
return (
<Grid gap="0.5rem" class={combineClasses("card shadow", themeClass())}>
<Flex alignItems="center" justifyContent="space-between">
<h1>{deployment()!.name}</h1>
<Show
when={permissions() >= 2 || deployment().owners.includes(username()!)}
>
<>
<Grid
gap="0.5rem"
class={combineClasses("card shadow", themeClass())}
style={{
position: "relative",
cursor: isMobile() ? "pointer" : undefined,
}}
onClick={() => {
if (isMobile()) toggleShowUpdates();
}}
>
<Flex alignItems="center" justifyContent="space-between">
<h1>{deployment()!.name}</h1>
<Show
when={!actions.fullDeleting}
fallback={
<Button class="red">
<Icon type="trash" />
</Button>
when={
permissions() >= 2 || deployment().owners.includes(username()!)
}
>
<HoverMenu
target={
<Show
when={!actions.fullDeleting}
fallback={
<Button class="red">
<Loading />
</Button>
}
>
<ConfirmButton
onConfirm={() => {
ws.send(DELETE_DEPLOYMENT, {
deploymentID: selected.id(),
});
}}
color="red"
>
<Icon type="trash" />
</ConfirmButton>
</Show>
<Show
when={!actions.fullDeleting}
fallback={
<Button class="red">
<Icon type="trash" />
</Button>
}
content="delete deployment"
position="bottom center"
padding="0.5rem"
/>
>
<HoverMenu
target={
<Show
when={!actions.fullDeleting}
fallback={
<Button class="red">
<Loading />
</Button>
}
>
<ConfirmButton
onConfirm={() => {
ws.send(DELETE_DEPLOYMENT, {
deploymentID: selected.id(),
});
}}
color="red"
>
<Icon type="trash" />
</ConfirmButton>
</Show>
}
content="delete deployment"
position="bottom center"
padding="0.5rem"
/>
</Show>
</Show>
</Flex>
<Flex alignItems="center" justifyContent="space-between">
<div class={deploymentHeaderStatusClass(state(), themeClass)}>
{state()}
</div>
<Show when={status()}>
<div style={{ opacity: 0.7 }}>{status()}</div>
</Show>
</Flex>
<Show when={isMobile()}>
<Flex gap="0.5rem" alignItems="center" class="show-updates-indicator">
updates{" "}
<Icon
type={showUpdates() ? "chevron-up" : "chevron-down"}
width="0.9rem"
/>
</Flex>
</Show>
</Flex>
<Flex alignItems="center" justifyContent="space-between">
<div class={deploymentHeaderStatusClass(state(), themeClass)}>{state()}</div>
<Show when={status()}>
<div style={{ opacity: 0.7 }}>{status()}</div>
</Show>
</Flex>
</Grid>
</Grid>
<Show when={isMobile() && showUpdates()}>
<Updates />
</Show>
</>
);
};
+54 -25
View File
@@ -9,6 +9,9 @@ import Icon from "../util/Icon";
import Flex from "../util/layout/Flex";
import Grid from "../util/layout/Grid";
import { useTheme } from "../../state/ThemeProvider";
import { useAppDimensions } from "../../state/DimensionProvider";
import { useLocalStorageToggle } from "../../util/hooks";
import Updates from "./Updates";
const Header: Component<{}> = (p) => {
const { servers, selected, ws } = useAppState();
@@ -21,34 +24,60 @@ const Header: Component<{}> = (p) => {
: "DISABLED";
const { permissions, username } = useUser();
const { themeClass } = useTheme();
const { isMobile } = useAppDimensions();
const [showUpdates, toggleShowUpdates] =
useLocalStorageToggle("show-updates");
return (
<Flex
class={combineClasses("card shadow", themeClass())}
justifyContent="space-between"
alignItems="center"
>
<Grid gap="0.1rem">
<h1>{server().name}</h1>
<div style={{ opacity: 0.8 }}>{server().address}</div>
</Grid>
<Show when={!server().isCore}>
<Flex alignItems="center">
<div class={serverStatusClass(status(), themeClass)}>{status()}</div>
<Show
when={permissions() > 1 || server().owners.includes(username())}
>
<ConfirmButton
onConfirm={() => {
ws.send(REMOVE_SERVER, { serverID: selected.id() });
}}
color="red"
<>
<Flex
class={combineClasses("card shadow", themeClass())}
justifyContent="space-between"
alignItems="center"
style={{
position: "relative",
cursor: isMobile() ? "pointer" : undefined,
}}
onClick={() => {
if (isMobile()) toggleShowUpdates();
}}
>
<Grid gap="0.1rem">
<h1>{server().name}</h1>
<div style={{ opacity: 0.8 }}>server</div>
</Grid>
<Show when={!server().isCore}>
<Flex alignItems="center">
<div class={serverStatusClass(status(), themeClass)}>
{status()}
</div>
<Show
when={permissions() > 1 || server().owners.includes(username())}
>
<Icon type="trash" />
</ConfirmButton>
</Show>
</Flex>
<ConfirmButton
onConfirm={() => {
ws.send(REMOVE_SERVER, { serverID: selected.id() });
}}
color="red"
>
<Icon type="trash" />
</ConfirmButton>
</Show>
</Flex>
</Show>
<Show when={isMobile()}>
<Flex gap="0.5rem" alignItems="center" class="show-updates-indicator">
updates{" "}
<Icon
type={showUpdates() ? "chevron-up" : "chevron-down"}
width="0.9rem"
/>
</Flex>
</Show>
</Flex>
<Show when={isMobile() && showUpdates()}>
<Updates />
</Show>
</Flex>
</>
);
};
+5 -1
View File
@@ -1,4 +1,5 @@
import { Component, Show } from "solid-js";
import { useAppDimensions } from "../../state/DimensionProvider";
import { useAppState } from "../../state/StateProvider";
import { useTheme } from "../../state/ThemeProvider";
import { combineClasses } from "../../util/helpers";
@@ -14,6 +15,7 @@ const Server: Component<{}> = (p) => {
const { servers, selected } = useAppState();
const server = () => servers.get(selected.id())!;
const { themeClass } = useTheme();
const { isMobile } = useAppDimensions();
return (
<Show when={server()} fallback={<NotFound type="server" />}>
<ActionStateProvider>
@@ -22,7 +24,9 @@ const Server: Component<{}> = (p) => {
<Grid class="left-content">
<Header />
<Actions />
<Updates />
<Show when={!isMobile()}>
<Updates />
</Show>
</Grid>
{/* right / tabs */}
<ServerTabs />
+1
View File
@@ -6,6 +6,7 @@ export type IconType =
| "arrow-up"
| "arrow-left"
| "chevron-down"
| "chevron-up"
| "cross"
| "double-chevron-right"
| "exchange"
+9
View File
@@ -110,6 +110,15 @@ $anim-time: 500ms;
max-height: calc(225px + 5.5rem);
}
.show-updates-indicator {
font-size: 0.8rem;
position: absolute;
bottom: 0.5rem;
left: 50%;
transform: translateX(-50%);
opacity: .7;
}
.tabs {
height: fit-content;
}