mirror of
https://github.com/moghtech/komodo.git
synced 2026-09-07 16:01:24 +00:00
make group behavior more sensible frontned
This commit is contained in:
@@ -14,7 +14,7 @@ export const NewGroup: Component<{}> = (p) => {
|
||||
<Show
|
||||
when={showNew()}
|
||||
fallback={
|
||||
<button class="green" onClick={toggleShowNew} style={{ width: "100%" }}>
|
||||
<button class="green" onClick={toggleShowNew} style={{ height: "100%" }}>
|
||||
<Icon type="plus" />
|
||||
</button>
|
||||
}
|
||||
@@ -100,12 +100,6 @@ const New: Component<{
|
||||
<button class="green" onClick={create}>
|
||||
create
|
||||
</button>
|
||||
{/* <ConfirmButton
|
||||
class="green"
|
||||
onConfirm={create}
|
||||
>
|
||||
create
|
||||
</ConfirmButton> */}
|
||||
<button class="red" onClick={p.close}>
|
||||
<Icon type="cross" />
|
||||
</button>
|
||||
|
||||
@@ -113,7 +113,7 @@ const Update: Component<{ update: UpdateType }> = (p) => {
|
||||
};
|
||||
return (
|
||||
<Flex
|
||||
class="card light shadow wrap"
|
||||
class="card light hover shadow wrap"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
>
|
||||
|
||||
@@ -7,7 +7,7 @@ import Grid from "../shared/layout/Grid";
|
||||
import SimpleTabs from "../shared/tabs/SimpleTabs";
|
||||
import Summary from "./Summary";
|
||||
import Builds from "./Tree/Builds";
|
||||
import Groups from "./Tree/Groups";
|
||||
import Groups from "./Tree/Groups2";
|
||||
import { TreeProvider } from "./Tree/Provider";
|
||||
import Servers from "./Tree/Servers";
|
||||
import Updates from "./Updates/Updates";
|
||||
@@ -30,13 +30,13 @@ const Home: Component<{}> = (p) => {
|
||||
localStorageKey="home-groups-servers-tab-v1"
|
||||
tabs={[
|
||||
{
|
||||
title: "groups",
|
||||
title: "servers",
|
||||
element: () => <Groups />,
|
||||
},
|
||||
{
|
||||
title: "servers",
|
||||
element: () => <Servers serverIDs={servers.ids()!} showAdd />,
|
||||
},
|
||||
// {
|
||||
// title: "servers",
|
||||
// element: () => <Servers serverIDs={servers.ids()!} showAdd />,
|
||||
// },
|
||||
{
|
||||
title: "builds",
|
||||
element: () => <Builds />
|
||||
|
||||
@@ -116,7 +116,7 @@ const Build: Component<{ id: string }> = (p) => {
|
||||
return (
|
||||
<A
|
||||
href={`/build/${p.id}`}
|
||||
class="card light shadow hoverable"
|
||||
class="card light shadow"
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "fit-content",
|
||||
|
||||
@@ -0,0 +1,280 @@
|
||||
import { Component, For, Show, createMemo, createSignal } from "solid-js";
|
||||
import Grid from "../../shared/layout/Grid";
|
||||
import { useLocalStorage, useToggle } from "../../../util/hooks";
|
||||
import Flex from "../../shared/layout/Flex";
|
||||
import { TREE_SORTS, TreeSortType, useTreeState } from "./Provider";
|
||||
import { useAppState } from "../../../state/StateProvider";
|
||||
import Input from "../../shared/Input";
|
||||
import Selector from "../../shared/menu/Selector";
|
||||
import { NewGroup } from "../../New";
|
||||
import Icon from "../../shared/Icon";
|
||||
import { useAppDimensions } from "../../../state/DimensionProvider";
|
||||
import ConfirmButton from "../../shared/ConfirmButton";
|
||||
import Server from "./Server";
|
||||
import { useWindowKeyDown } from "../../../util/hooks";
|
||||
import Menu from "../../shared/menu/Menu";
|
||||
import { client } from "../../..";
|
||||
|
||||
const Groups: Component<{}> = (p) => {
|
||||
const { isSemiMobile } = useAppDimensions();
|
||||
const { groups } = useAppState();
|
||||
const [selected, setSelected] = useLocalStorage<string | null>(
|
||||
null,
|
||||
"home-selected-group-v1"
|
||||
);
|
||||
const [searchFilter, setSearchFilter] = createSignal("");
|
||||
const { sort, setSort, group_sorter } = useTreeState();
|
||||
const [editing, toggleEditing, setEditing] = useToggle();
|
||||
const groupIDs = createMemo(() => {
|
||||
if (groups.loaded()) {
|
||||
const filters = searchFilter()
|
||||
.split(" ")
|
||||
.filter((term) => term.length > 0)
|
||||
.map((term) => term.toLowerCase());
|
||||
return groups
|
||||
.ids()
|
||||
?.filter((id) => {
|
||||
const name = groups.get(id)!.name;
|
||||
for (const term of filters) {
|
||||
if (!name.includes(term)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.sort(group_sorter());
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
return (
|
||||
<Grid class="full-width">
|
||||
<Grid gridTemplateColumns={selected() ? "auto 1fr auto" : "1fr auto"}>
|
||||
<Show when={selected()}>
|
||||
<Flex alignItems="center">
|
||||
<button class="grey" onClick={() => setSelected(null)}>
|
||||
<Icon type="arrow-left" />
|
||||
</button>
|
||||
<h1 style={{ margin: "0 1rem" }}>
|
||||
{selected() === "all" ? "all" : groups.get(selected()!)?.name}
|
||||
</h1>
|
||||
</Flex>
|
||||
</Show>
|
||||
<Input
|
||||
placeholder={`filter ${selected() ? "servers" : "groups"}`}
|
||||
value={searchFilter()}
|
||||
onEdit={setSearchFilter}
|
||||
style={{ width: "100%", padding: "0.5rem" }}
|
||||
/>
|
||||
<Flex alignItems="center" style={{ width: "fit-content" }}>
|
||||
<Selector
|
||||
label={<div class="dimmed">sort by:</div>}
|
||||
selected={sort()}
|
||||
items={TREE_SORTS as any as string[]}
|
||||
onSelect={(mode) => setSort(mode as TreeSortType)}
|
||||
position="bottom right"
|
||||
targetClass="blue"
|
||||
targetStyle={{ height: "100%" }}
|
||||
containerStyle={{ height: "100%" }}
|
||||
/>
|
||||
<Show when={selected()} fallback={<NewGroup />}>
|
||||
<Show when={selected() !== "all"}>
|
||||
<button
|
||||
class="blue"
|
||||
onClick={toggleEditing}
|
||||
style={{ height: "100%" }}
|
||||
>
|
||||
<Icon type="edit" />
|
||||
</button>
|
||||
<AddServerToGroup groupId={selected()!} />
|
||||
</Show>
|
||||
</Show>
|
||||
</Flex>
|
||||
</Grid>
|
||||
<Show
|
||||
when={selected()}
|
||||
fallback={
|
||||
<Grid gridTemplateColumns={isSemiMobile() ? "1fr" : "1fr 1fr"}>
|
||||
<GroupButton id="all" setSelected={setSelected} />
|
||||
<For each={groupIDs()}>
|
||||
{(id) => <GroupButton id={id} setSelected={setSelected} />}
|
||||
</For>
|
||||
</Grid>
|
||||
}
|
||||
>
|
||||
<Group
|
||||
id={selected()!}
|
||||
searchFilter={searchFilter()}
|
||||
exit={() => {
|
||||
setSelected(null);
|
||||
setEditing(false);
|
||||
}}
|
||||
editing={editing()}
|
||||
/>
|
||||
</Show>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
export default Groups;
|
||||
|
||||
const GroupButton: Component<{
|
||||
id: string;
|
||||
setSelected: (s: string) => void;
|
||||
}> = (p) => {
|
||||
const { isSemiMobile } = useAppDimensions();
|
||||
const { groups, servers } = useAppState();
|
||||
const isAll = () => p.id === "all";
|
||||
const name = () => {
|
||||
if (isAll()) {
|
||||
return "all";
|
||||
}
|
||||
return groups.get(p.id)?.name;
|
||||
};
|
||||
const serverCount = () => {
|
||||
if (isAll()) {
|
||||
return servers.ids()?.length || 0;
|
||||
}
|
||||
return groups.get(p.id)?.servers.length || 0;
|
||||
};
|
||||
return (
|
||||
<Flex
|
||||
class="card light hover shadow"
|
||||
style={{
|
||||
"grid-column": isAll() && !isSemiMobile() ? "span 2" : undefined,
|
||||
"justify-content": "space-between",
|
||||
cursor: "pointer",
|
||||
}}
|
||||
onClick={() => p.setSelected(p.id)}
|
||||
>
|
||||
<h1>{name()}</h1>
|
||||
<Flex alignItems="center">
|
||||
<Flex gap="0.4rem">
|
||||
<div>{serverCount()}</div>
|
||||
<div class="dimmed">{`server${serverCount() > 1 ? "s" : ""}`}</div>
|
||||
</Flex>
|
||||
<Show when={!isAll()}>
|
||||
<ConfirmButton class="red">
|
||||
<Icon type="trash" />
|
||||
</ConfirmButton>
|
||||
</Show>
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
const Group: Component<{
|
||||
id: string;
|
||||
searchFilter: string;
|
||||
editing: boolean;
|
||||
exit: () => void;
|
||||
}> = (p) => {
|
||||
const { groups, servers } = useAppState();
|
||||
const { server_sorter } = useTreeState();
|
||||
const group = () => groups.get(p.id);
|
||||
const serverIDs = createMemo(() => {
|
||||
if (servers.loaded()) {
|
||||
const filters = p.searchFilter
|
||||
.split(" ")
|
||||
.filter((term) => term.length > 0)
|
||||
.map((term) => term.toLowerCase());
|
||||
const serverIds = (
|
||||
p.id === "all" ? servers.ids() : groups.get(p.id)?.servers
|
||||
)?.sort(server_sorter());
|
||||
return serverIds
|
||||
?.filter((id) => {
|
||||
const name = servers.get(id)!.server.name;
|
||||
for (const term of filters) {
|
||||
if (!name.includes(term)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.sort(server_sorter());
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
useWindowKeyDown((e) => {
|
||||
if (e.key === "ArrowLeft") {
|
||||
p.exit();
|
||||
}
|
||||
});
|
||||
return (
|
||||
<For each={serverIDs()}>
|
||||
{(id) => (
|
||||
<Flex alignItems="center">
|
||||
<Server id={id} />
|
||||
<Show when={p.editing}>
|
||||
<ConfirmButton
|
||||
class="red"
|
||||
onConfirm={() => {
|
||||
client.update_group({
|
||||
...group()!,
|
||||
servers: group()!.servers.filter((member) => member !== id),
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Icon type="minus" />
|
||||
</ConfirmButton>
|
||||
</Show>
|
||||
</Flex>
|
||||
)}
|
||||
</For>
|
||||
);
|
||||
};
|
||||
|
||||
const AddServerToGroup: Component<{ groupId: string }> = (p) => {
|
||||
const { groups, servers, ungroupedServerIds } = useAppState();
|
||||
const [showAdd, setShowAdd] = createSignal(false);
|
||||
const group = () => groups.get(p.groupId);
|
||||
return (
|
||||
<Show when={(group() && ungroupedServerIds()?.length) || 0 > 0}>
|
||||
<Menu
|
||||
show={showAdd()}
|
||||
close={(e) => {
|
||||
e.stopPropagation();
|
||||
setShowAdd(false);
|
||||
}}
|
||||
position="bottom right"
|
||||
target={
|
||||
<button
|
||||
class="green"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
setShowAdd(true);
|
||||
}}
|
||||
>
|
||||
<Icon type="plus" />
|
||||
</button>
|
||||
}
|
||||
menuStyle={{ gap: "0.5rem" }}
|
||||
content={
|
||||
<>
|
||||
{/* <Input placeholder="search" style={{ width: "10rem" }} /> */}
|
||||
<For each={ungroupedServerIds()!}>
|
||||
{(server_id) => {
|
||||
const server = () => servers.get(server_id)!;
|
||||
return (
|
||||
<ConfirmButton
|
||||
class="lightgrey"
|
||||
style={{ width: "100%" }}
|
||||
onConfirm={() =>
|
||||
client.update_group({
|
||||
...group()!,
|
||||
servers: [...group()!.servers, server_id],
|
||||
})
|
||||
}
|
||||
>
|
||||
{server().server.name}
|
||||
</ConfirmButton>
|
||||
);
|
||||
}}
|
||||
</For>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</Show>
|
||||
);
|
||||
};
|
||||
@@ -18,9 +18,10 @@ const Server: Component<{ id: string }> = (p) => {
|
||||
const server = () => servers.get(p.id);
|
||||
return (
|
||||
<Show when={server()}>
|
||||
<div class={combineClasses(s.Server, "shadow")}>
|
||||
<Grid class="shadow pointer full-width" style={{ height: "fit-content" }} gap="0">
|
||||
<button
|
||||
class={combineClasses(s.ServerButton, "shadow")}
|
||||
class="card light hover shadow full-width"
|
||||
style={{ "justify-content": "space-between" }}
|
||||
onClick={toggleOpen}
|
||||
>
|
||||
<Flex>
|
||||
@@ -54,7 +55,7 @@ const Server: Component<{ id: string }> = (p) => {
|
||||
<Show when={open()}>
|
||||
<ServerChildren id={p.id} />
|
||||
</Show>
|
||||
</div>
|
||||
</Grid>
|
||||
</Show>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useUser } from "../../../state/UserProvider";
|
||||
import Input from "../../shared/Input";
|
||||
import Grid from "../../shared/layout/Grid";
|
||||
import Selector from "../../shared/menu/Selector";
|
||||
import AddServer from "./AddServer";
|
||||
import AddServer from "../../topbar/AddServer";
|
||||
import { TreeSortType, TREE_SORTS, useTreeState } from "./Provider";
|
||||
import Server from "./Server";
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ const Update: Component<{ update: UpdateType }> = (p) => {
|
||||
};
|
||||
return (
|
||||
<Flex
|
||||
class={combineClasses(s.Update, "shadow")}
|
||||
class={combineClasses(s.Update, "card light hover shadow")}
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
>
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
}
|
||||
|
||||
.Update {
|
||||
background-color: c.$lightgrey;
|
||||
padding: 0.75rem;
|
||||
height: 40px;
|
||||
transform-origin: top;
|
||||
|
||||
@@ -51,7 +51,7 @@ const Deployment: Component<{ id: string }> = (p) => {
|
||||
<Show when={deployment()}>
|
||||
<A
|
||||
href={`/deployment/${p.id}`}
|
||||
class="card hoverable"
|
||||
class="card clear hover"
|
||||
style={{
|
||||
width: "100%",
|
||||
"justify-content": "space-between",
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { Component, createMemo, For, Show } from "solid-js";
|
||||
import { useAppDimensions } from "../../state/DimensionProvider";
|
||||
import { combineClasses, getId } from "../../util/helpers";
|
||||
import { getId } from "../../util/helpers";
|
||||
import Grid from "../shared/layout/Grid";
|
||||
import SimpleTabs from "../shared/tabs/SimpleTabs";
|
||||
import s from "./serverchildren.module.scss";
|
||||
import { useUser } from "../../state/UserProvider";
|
||||
import { PermissionLevel } from "../../types";
|
||||
import { NewDeployment } from "../New";
|
||||
@@ -23,17 +21,11 @@ const ServerChildren: Component<{ id: string }> = (p) => {
|
||||
(id) => deployments.get(id)?.deployment.server_id === p.id
|
||||
)) as string[];
|
||||
});
|
||||
// const buildIDs = createMemo(() => {
|
||||
// return (builds.loaded() &&
|
||||
// builds
|
||||
// .ids()!
|
||||
// .filter((id) => builds.get(id)?.server_id === p.id)) as string[];
|
||||
// });
|
||||
return (
|
||||
<div class="card shadow">
|
||||
<Grid
|
||||
gap=".5rem"
|
||||
gridTemplateColumns={isSemiMobile() ? "1fr" : "1fr 1fr"}
|
||||
gap="0.5rem"
|
||||
>
|
||||
<For each={deploymentIDs()}>{(id) => <Deployment id={id} />}</For>
|
||||
<Show
|
||||
@@ -47,54 +39,6 @@ const ServerChildren: Component<{ id: string }> = (p) => {
|
||||
</Show>
|
||||
</Grid>
|
||||
</div>
|
||||
// <SimpleTabs
|
||||
// containerClass="card shadow"
|
||||
// localStorageKey={`${p.id}-home-tab`}
|
||||
// tabs={[
|
||||
// {
|
||||
// title: "deployments",
|
||||
// element: () => (
|
||||
// <Grid
|
||||
// gap=".5rem"
|
||||
// class={combineClasses(s.Deployments)}
|
||||
// gridTemplateColumns={isSemiMobile() ? "1fr" : "1fr 1fr"}
|
||||
// >
|
||||
// <For each={deploymentIDs()}>{(id) => <Deployment id={id} />}</For>
|
||||
// <Show
|
||||
// when={
|
||||
// user().admin ||
|
||||
// server()?.server.permissions![getId(user())] ===
|
||||
// PermissionLevel.Update
|
||||
// }
|
||||
// >
|
||||
// <NewDeployment serverID={p.id} />
|
||||
// </Show>
|
||||
// </Grid>
|
||||
// ),
|
||||
// },
|
||||
// // {
|
||||
// // title: "builds",
|
||||
// // element: () => (
|
||||
// // <Grid
|
||||
// // gap=".5rem"
|
||||
// // class={combineClasses(s.Deployments)}
|
||||
// // gridTemplateColumns={isSemiMobile() ? "1fr" : "1fr 1fr"}
|
||||
// // >
|
||||
// // <For each={buildIDs()}>{(id) => <Build id={id} />}</For>
|
||||
// // <Show
|
||||
// // when={
|
||||
// // user().admin ||
|
||||
// // server()?.server.permissions![getId(user())] ===
|
||||
// // PermissionLevel.Update
|
||||
// // }
|
||||
// // >
|
||||
// // <NewBuild serverID={p.id} />
|
||||
// // </Show>
|
||||
// // </Grid>
|
||||
// // ),
|
||||
// // },
|
||||
// ]}
|
||||
// />
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
+16
-10
@@ -1,12 +1,12 @@
|
||||
import { Component, JSX, onMount } from "solid-js";
|
||||
import { createStore } from "solid-js/store";
|
||||
import { client, pushNotification } from "../../..";
|
||||
import { CreateServerBody } from "../../../util/client_types";
|
||||
import { useToggle } from "../../../util/hooks";
|
||||
import Icon from "../../shared/Icon";
|
||||
import Input from "../../shared/Input";
|
||||
import Grid from "../../shared/layout/Grid";
|
||||
import CenterMenu from "../../shared/menu/CenterMenu";
|
||||
import { client, pushNotification } from "../..";
|
||||
import { CreateServerBody } from "../../util/client_types";
|
||||
import { useToggle } from "../../util/hooks";
|
||||
import Icon from "../shared/Icon";
|
||||
import Input from "../shared/Input";
|
||||
import Grid from "../shared/layout/Grid";
|
||||
import CenterMenu from "../shared/menu/CenterMenu";
|
||||
|
||||
const AddServer: Component<{}> = () => {
|
||||
const [show, toggleShow] = useToggle();
|
||||
@@ -14,10 +14,11 @@ const AddServer: Component<{}> = () => {
|
||||
<CenterMenu
|
||||
show={show}
|
||||
toggleShow={toggleShow}
|
||||
target={<Icon type="plus" />}
|
||||
target="add server"
|
||||
title="add server"
|
||||
targetClass="green shadow"
|
||||
content={() => <Content close={toggleShow} />}
|
||||
style={{ "box-sizing": "border-box", "max-width": "90vw" }}
|
||||
position="center"
|
||||
/>
|
||||
);
|
||||
@@ -26,7 +27,7 @@ const AddServer: Component<{}> = () => {
|
||||
const INPUT_STYLE: JSX.CSSProperties = {
|
||||
"font-size": "1.25rem",
|
||||
width: "500px",
|
||||
"max-width": "90vw",
|
||||
"max-width": "80vw",
|
||||
};
|
||||
|
||||
const Content: Component<{ close: () => void }> = (p) => {
|
||||
@@ -45,7 +46,12 @@ const Content: Component<{ close: () => void }> = (p) => {
|
||||
}
|
||||
};
|
||||
return (
|
||||
<Grid placeItems="center" style={{ padding: "2rem 1rem 1rem 1rem" }}>
|
||||
<Grid
|
||||
placeItems="center"
|
||||
style={{
|
||||
|
||||
}}
|
||||
>
|
||||
<Input
|
||||
class="darkgrey"
|
||||
ref={nameInput}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { A, useNavigate } from "@solidjs/router";
|
||||
import { Component, createSignal, JSX, Show } from "solid-js";
|
||||
import { A } from "@solidjs/router";
|
||||
import { Component, createSignal, Show } from "solid-js";
|
||||
import { TOPBAR_HEIGHT } from "../..";
|
||||
import { useAppDimensions } from "../../state/DimensionProvider";
|
||||
import { useAppState } from "../../state/StateProvider";
|
||||
@@ -15,14 +15,7 @@ import Account from "./Account";
|
||||
import { SearchProvider } from "./Search/Provider";
|
||||
import { Search } from "./Search/Search";
|
||||
import s from "./topbar.module.scss";
|
||||
import Updates from "./Updates/Updates";
|
||||
|
||||
const mobileStyle: JSX.CSSProperties = {
|
||||
position: "fixed",
|
||||
top: inPx(44),
|
||||
left: "1rem",
|
||||
width: "calc(100vw - 2rem)",
|
||||
};
|
||||
import AddServer from "./AddServer";
|
||||
|
||||
const Topbar: Component = () => {
|
||||
return (
|
||||
@@ -102,6 +95,7 @@ const RightSide: Component = () => {
|
||||
content={<Updates />}
|
||||
position="bottom right"
|
||||
/> */}
|
||||
<AddServer />
|
||||
<Menu
|
||||
show={menu() === "account"}
|
||||
close={close}
|
||||
|
||||
@@ -156,8 +156,10 @@ export const AppStateProvider: ParentComponent = (p) => {
|
||||
return servers.get(target.id)?.server.name || "deleted";
|
||||
} else if (target.type === "Build" && builds) {
|
||||
return builds.get(target.id)?.name || "deleted";
|
||||
} else if (target.type === "Group" && groups) {
|
||||
return groups.get(target.id)?.name || "deleted";
|
||||
} else {
|
||||
return "admin";
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -35,17 +35,37 @@
|
||||
}
|
||||
|
||||
.card {
|
||||
background-color: c.$grey;
|
||||
background-color: rgba(c.$grey, 0.7);
|
||||
padding: 1rem;
|
||||
transition: all 250ms ease-in-out;
|
||||
}
|
||||
|
||||
.card.hover:hover {
|
||||
background-color: c.$grey;
|
||||
}
|
||||
|
||||
.card.clear {
|
||||
background-color: rgba(c.$lightgrey, 0);
|
||||
}
|
||||
|
||||
.card.clear.hover:hover {
|
||||
background-color: rgba(c.$lightgrey, 0.7);
|
||||
}
|
||||
|
||||
.card.light {
|
||||
background-color: c.$lightgrey;
|
||||
background-color: rgba(c.$lightgrey, 0.7);
|
||||
}
|
||||
|
||||
.card.light.hover:hover {
|
||||
background-color: c.$lightgrey;
|
||||
}
|
||||
|
||||
.card.dark {
|
||||
background-color: c.$darkgrey;
|
||||
background-color: rgba(c.$darkgrey, 0.7);
|
||||
}
|
||||
|
||||
.card.dark.hover:hover {
|
||||
background-color: c.$darkgrey;
|
||||
}
|
||||
|
||||
.card.hoverable:hover {
|
||||
|
||||
Reference in New Issue
Block a user