mirror of
https://github.com/speatzle/nfsense.git
synced 2025-05-11 19:08:20 +00:00
commit
84ee950b83
6 changed files with 162 additions and 57 deletions
|
@ -23,6 +23,7 @@
|
||||||
"simple-jsonrpc-js": "^1.2.0",
|
"simple-jsonrpc-js": "^1.2.0",
|
||||||
"vue": "^3.2.45",
|
"vue": "^3.2.45",
|
||||||
"vue-i18n": "9",
|
"vue-i18n": "9",
|
||||||
|
"vue-multiselect": "3.0.0-beta.1",
|
||||||
"vue-router": "4",
|
"vue-router": "4",
|
||||||
"ws": "^8.13.0"
|
"ws": "^8.13.0"
|
||||||
},
|
},
|
||||||
|
|
7
client/pnpm-lock.yaml
generated
7
client/pnpm-lock.yaml
generated
|
@ -30,6 +30,7 @@ specifiers:
|
||||||
vite-plugin-vue-markdown: ^0.22.4
|
vite-plugin-vue-markdown: ^0.22.4
|
||||||
vue: ^3.2.45
|
vue: ^3.2.45
|
||||||
vue-i18n: '9'
|
vue-i18n: '9'
|
||||||
|
vue-multiselect: 3.0.0-beta.1
|
||||||
vue-router: '4'
|
vue-router: '4'
|
||||||
vue-tsc: ^1.0.24
|
vue-tsc: ^1.0.24
|
||||||
ws: ^8.13.0
|
ws: ^8.13.0
|
||||||
|
@ -47,6 +48,7 @@ dependencies:
|
||||||
simple-jsonrpc-js: 1.2.0
|
simple-jsonrpc-js: 1.2.0
|
||||||
vue: 3.2.47
|
vue: 3.2.47
|
||||||
vue-i18n: 9.2.2_vue@3.2.47
|
vue-i18n: 9.2.2_vue@3.2.47
|
||||||
|
vue-multiselect: 3.0.0-beta.1
|
||||||
vue-router: 4.1.6_vue@3.2.47
|
vue-router: 4.1.6_vue@3.2.47
|
||||||
ws: 8.13.0
|
ws: 8.13.0
|
||||||
|
|
||||||
|
@ -3829,6 +3831,11 @@ packages:
|
||||||
vue: 3.2.47
|
vue: 3.2.47
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/vue-multiselect/3.0.0-beta.1:
|
||||||
|
resolution: {integrity: sha512-V+jpydtjyHcQ+yjHsEWEBrDAopOx/pufNkSAXNVDAGQ+ESDEJ7wYejNd9H1RiCnFOYK4yf1XSGqE+Mp3HJXmdg==}
|
||||||
|
engines: {node: '>= 4.0.0', npm: '>= 3.0.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/vue-router/4.1.6_vue@3.2.47:
|
/vue-router/4.1.6_vue@3.2.47:
|
||||||
resolution: {integrity: sha512-DYWYwsG6xNPmLq/FmZn8Ip+qrhFEzA14EI12MsMgVxvHFDYvlr4NXpVF5hrRH1wVcDP8fGi5F4rxuJSl8/r+EQ==}
|
resolution: {integrity: sha512-DYWYwsG6xNPmLq/FmZn8Ip+qrhFEzA14EI12MsMgVxvHFDYvlr4NXpVF5hrRH1wVcDP8fGi5F4rxuJSl8/r+EQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|
|
@ -97,14 +97,14 @@ onMounted(async() => {
|
||||||
'nav-state-collapsed': navState === NavState.Collapsed,
|
'nav-state-collapsed': navState === NavState.Collapsed,
|
||||||
'nav-state-reduced': navState === NavState.Reduced,
|
'nav-state-reduced': navState === NavState.Reduced,
|
||||||
}">
|
}">
|
||||||
<button class="nav-head" @click="toggleNavState">
|
<button class="nav-head cl-secondary" @click="toggleNavState">
|
||||||
<i-mdi-hamburger-menu/>
|
<i-mdi-hamburger-menu/>
|
||||||
<h1>nfSense</h1>
|
<h1>nfSense</h1>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<Portal from="page-header" class="page-header pad gap"/>
|
<Portal from="page-header" class="page-header pad gap"/>
|
||||||
|
|
||||||
<div class="nav-body">
|
<div class="nav-body cl-secondary">
|
||||||
<template v-for="(options, route) in navRoutes" :key="route">
|
<template v-for="(options, route) in navRoutes" :key="route">
|
||||||
<router-link :to="route" class="button" @click="collapseNavIfMobile">
|
<router-link :to="route" class="button" @click="collapseNavIfMobile">
|
||||||
<component :is="options.icon"/>
|
<component :is="options.icon"/>
|
||||||
|
@ -118,6 +118,7 @@ onMounted(async() => {
|
||||||
<button @click="tryLogout"><i-material-symbols-logout/></button>
|
<button @click="tryLogout"><i-material-symbols-logout/></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<router-view v-slot="{ Component, route }" v-if="authState === AuthState.Authenticated">
|
<router-view v-slot="{ Component, route }" v-if="authState === AuthState.Authenticated">
|
||||||
<Transition name="fade">
|
<Transition name="fade">
|
||||||
<component :is="Component" :key="{route}" class="page-content pad gap"/>
|
<component :is="Component" :key="{route}" class="page-content pad gap"/>
|
||||||
|
@ -128,7 +129,7 @@ onMounted(async() => {
|
||||||
<Transition name="fade">
|
<Transition name="fade">
|
||||||
<div class="login" v-if="authState === AuthState.Unauthenticated">
|
<div class="login" v-if="authState === AuthState.Unauthenticated">
|
||||||
<FocusTrap>
|
<FocusTrap>
|
||||||
<form @submit="$event => $event.preventDefault()" :disabled="loginDisabled">
|
<form @submit="$event => $event.preventDefault()" :disabled="loginDisabled" class="cl-secondary">
|
||||||
<h1>nfSense Login</h1>
|
<h1>nfSense Login</h1>
|
||||||
<h2 :hidden="!loginDisabled">Logging in...</h2>
|
<h2 :hidden="!loginDisabled">Logging in...</h2>
|
||||||
<label for="username" v-text="'Username'" :hidden="loginDisabled" />
|
<label for="username" v-text="'Username'" :hidden="loginDisabled" />
|
||||||
|
@ -149,7 +150,6 @@ onMounted(async() => {
|
||||||
left: 0px; right: 0px; top: 0px; bottom: 0px;
|
left: 0px; right: 0px; top: 0px; bottom: 0px;
|
||||||
|
|
||||||
display: grid;
|
display: grid;
|
||||||
background-color: var(--cl-bg);
|
|
||||||
}
|
}
|
||||||
.layout {
|
.layout {
|
||||||
grid-template-rows: auto 1fr;
|
grid-template-rows: auto 1fr;
|
||||||
|
@ -165,9 +165,6 @@ onMounted(async() => {
|
||||||
.page-header { grid-area: PH; }
|
.page-header { grid-area: PH; }
|
||||||
.page-content { grid-area: PC; }
|
.page-content { grid-area: PC; }
|
||||||
|
|
||||||
/* Navigation */
|
|
||||||
.nav-head, .nav-body { background: var(--cl-bg-low); }
|
|
||||||
|
|
||||||
.nav-head { font-weight: bold; }
|
.nav-head { font-weight: bold; }
|
||||||
.nav-head > svg { display: none; }
|
.nav-head > svg { display: none; }
|
||||||
.nav-head > h1 { flex-grow: 1; }
|
.nav-head > h1 { flex-grow: 1; }
|
||||||
|
@ -181,7 +178,6 @@ onMounted(async() => {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
.page-header button svg { margin: -0.25rem; }
|
.page-header button svg { margin: -0.25rem; }
|
||||||
.page-content { background: var(--cl-bg); }
|
|
||||||
|
|
||||||
/* Nav-Body-Collapsing */
|
/* Nav-Body-Collapsing */
|
||||||
.nav-body, .page-header, .page-content {
|
.nav-body, .page-header, .page-content {
|
||||||
|
|
|
@ -1,34 +1,121 @@
|
||||||
/* Coloring */
|
/* --- YACS --- */
|
||||||
:root {
|
:root {
|
||||||
/* Color Definitions */
|
/* Light/Dark-Agnostic Base Tints, defined as HSL */
|
||||||
--cl-md-50: #FAFAFA;
|
--cl-base-0-h: 260;
|
||||||
--cl-md-100: #F5F5F5;
|
/* Color 0 Base Hue */
|
||||||
--cl-md-200: #EEEEEE;
|
--cl-base-0-s: 20%;
|
||||||
--cl-md-300: #E0E0E0;
|
/* Color 0 Base Saturation */
|
||||||
--cl-md-400: #BDBDBD;
|
--cl-base-0-l: 100%;
|
||||||
--cl-md-500: #9E9E9E;
|
/* Color 0 Base Lightness (Only usefull for darkening really) */
|
||||||
--cl-md-600: #757575;
|
--cl-base-1-h: 260;
|
||||||
--cl-md-700: #616161;
|
/* Same definitions for another tint */
|
||||||
--cl-md-800: #424242;
|
--cl-base-1-s: 50%;
|
||||||
--cl-md-900: #212121;
|
--cl-base-1-l: 100%;
|
||||||
|
|
||||||
/* Color Uses */
|
/* --- Linear Scaling with buffer --- */
|
||||||
--cl-bg: var(--cl-md-900);
|
--lin-0-buf: 5%;
|
||||||
--cl-bg-mid: var(--cl-md-800);
|
/* Edge-Buffer for lightness spectrum, reduces contrast */
|
||||||
--cl-bg-low: var(--cl-md-700);
|
--lin-0-flux: calc(var(--cl-base-0-l) - var(--lin-0-buf) * 2);
|
||||||
--cl-fg: var(--cl-md-100);
|
/* Variable Lightness Space */
|
||||||
|
--lin-0-step: calc(var(--lin-0-flux) / 7);
|
||||||
|
/* Increment per Step, 8 steps - 1 = 7 increments */
|
||||||
|
/* Actual color steps */
|
||||||
|
--cl-base-0-1: hsl(var(--cl-base-0-h), var(--cl-base-0-s), calc(var(--lin-0-buf) + var(--lin-0-step) * 0));
|
||||||
|
--cl-base-0-2: hsl(var(--cl-base-0-h), var(--cl-base-0-s), calc(var(--lin-0-buf) + var(--lin-0-step) * 1));
|
||||||
|
--cl-base-0-3: hsl(var(--cl-base-0-h), var(--cl-base-0-s), calc(var(--lin-0-buf) + var(--lin-0-step) * 2));
|
||||||
|
--cl-base-0-4: hsl(var(--cl-base-0-h), var(--cl-base-0-s), calc(var(--lin-0-buf) + var(--lin-0-step) * 3));
|
||||||
|
--cl-base-0-5: hsl(var(--cl-base-0-h), var(--cl-base-0-s), calc(var(--lin-0-buf) + var(--lin-0-step) * 4));
|
||||||
|
--cl-base-0-6: hsl(var(--cl-base-0-h), var(--cl-base-0-s), calc(var(--lin-0-buf) + var(--lin-0-step) * 5));
|
||||||
|
--cl-base-0-7: hsl(var(--cl-base-0-h), var(--cl-base-0-s), calc(var(--lin-0-buf) + var(--lin-0-step) * 6));
|
||||||
|
--cl-base-0-8: hsl(var(--cl-base-0-h), var(--cl-base-0-s), calc(var(--lin-0-buf) + var(--lin-0-step) * 7));
|
||||||
|
|
||||||
/* Apply as default */
|
/* Repeated for another Tint */
|
||||||
|
--lin-1-buf: 5%;
|
||||||
|
--lin-1-flux: calc(var(--cl-base-1-l) - var(--lin-1-buf) * 2);
|
||||||
|
--lin-1-step: calc(var(--lin-1-flux) / 7);
|
||||||
|
--cl-base-1-1: hsl(var(--cl-base-1-h), var(--cl-base-1-s), calc(var(--lin-1-buf) + var(--lin-1-step) * 0));
|
||||||
|
--cl-base-1-2: hsl(var(--cl-base-1-h), var(--cl-base-1-s), calc(var(--lin-1-buf) + var(--lin-1-step) * 1));
|
||||||
|
--cl-base-1-3: hsl(var(--cl-base-1-h), var(--cl-base-1-s), calc(var(--lin-1-buf) + var(--lin-1-step) * 2));
|
||||||
|
--cl-base-1-4: hsl(var(--cl-base-1-h), var(--cl-base-1-s), calc(var(--lin-1-buf) + var(--lin-1-step) * 3));
|
||||||
|
--cl-base-1-5: hsl(var(--cl-base-1-h), var(--cl-base-1-s), calc(var(--lin-1-buf) + var(--lin-1-step) * 4));
|
||||||
|
--cl-base-1-6: hsl(var(--cl-base-1-h), var(--cl-base-1-s), calc(var(--lin-1-buf) + var(--lin-1-step) * 5));
|
||||||
|
--cl-base-1-7: hsl(var(--cl-base-1-h), var(--cl-base-1-s), calc(var(--lin-1-buf) + var(--lin-1-step) * 6));
|
||||||
|
--cl-base-1-8: hsl(var(--cl-base-1-h), var(--cl-base-1-s), calc(var(--lin-1-buf) + var(--lin-1-step) * 7));
|
||||||
|
|
||||||
|
/* Dark Mode Colors*/
|
||||||
|
--cl-0-1: var(--cl-base-0-1);
|
||||||
|
--cl-0-2: var(--cl-base-0-2);
|
||||||
|
--cl-0-3: var(--cl-base-0-3);
|
||||||
|
--cl-0-4: var(--cl-base-0-4);
|
||||||
|
--cl-0-5: var(--cl-base-0-5);
|
||||||
|
--cl-0-6: var(--cl-base-0-6);
|
||||||
|
--cl-0-7: var(--cl-base-0-7);
|
||||||
|
--cl-0-8: var(--cl-base-0-8);
|
||||||
|
|
||||||
|
--cl-1-1: var(--cl-base-1-1);
|
||||||
|
--cl-1-2: var(--cl-base-1-2);
|
||||||
|
--cl-1-3: var(--cl-base-1-3);
|
||||||
|
--cl-1-4: var(--cl-base-1-4);
|
||||||
|
--cl-1-5: var(--cl-base-1-5);
|
||||||
|
--cl-1-6: var(--cl-base-1-6);
|
||||||
|
--cl-1-7: var(--cl-base-1-7);
|
||||||
|
--cl-1-8: var(--cl-base-1-8);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (prefers-color-scheme: light) {
|
||||||
|
|
||||||
|
/* Light Mode Colors, simply inverts the spectrum */
|
||||||
|
:root {
|
||||||
|
--cl-0-1: var(--cl-base-0-8);
|
||||||
|
--cl-0-2: var(--cl-base-0-7);
|
||||||
|
--cl-0-3: var(--cl-base-0-6);
|
||||||
|
--cl-0-4: var(--cl-base-0-5);
|
||||||
|
--cl-0-5: var(--cl-base-0-4);
|
||||||
|
--cl-0-6: var(--cl-base-0-3);
|
||||||
|
--cl-0-7: var(--cl-base-0-2);
|
||||||
|
--cl-0-8: var(--cl-base-0-1);
|
||||||
|
|
||||||
|
--cl-1-1: var(--cl-base-1-8);
|
||||||
|
--cl-1-2: var(--cl-base-1-7);
|
||||||
|
--cl-1-3: var(--cl-base-1-6);
|
||||||
|
--cl-1-4: var(--cl-base-1-5);
|
||||||
|
--cl-1-5: var(--cl-base-1-4);
|
||||||
|
--cl-1-6: var(--cl-base-1-3);
|
||||||
|
--cl-1-7: var(--cl-base-1-2);
|
||||||
|
--cl-1-8: var(--cl-base-1-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Color Contexts --- */
|
||||||
|
/* These Contexts are meant to make it easy to shift all color assignments for differentiated areas, like navigation bars or context menus */
|
||||||
|
/* Primary Color Context */
|
||||||
|
:root, .cl-primary {
|
||||||
|
/* Color assignments, these finally have semantic value and will be used to style components. */
|
||||||
|
/* More can be added as needed. */
|
||||||
|
--cl-fg: var(--cl-0-8);
|
||||||
|
/* Foreground (Text, outlines) */
|
||||||
|
--cl-bg: var(--cl-0-1);
|
||||||
|
/* Background */
|
||||||
|
--cl-bg-hl: var(--cl-1-2);
|
||||||
|
/* Highlight Background (Component on Hover, select, ...) */
|
||||||
|
--cl-bg-el: var(--cl-1-3);
|
||||||
|
/* Element Background (Component) */
|
||||||
|
|
||||||
|
/* Set Default Colors */
|
||||||
background-color: var(--cl-bg);
|
background-color: var(--cl-bg);
|
||||||
color: var(--cl-fg);
|
color: var(--cl-fg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Changes for light mode */
|
/* Secondary Color Context, in this case for the sidebar */
|
||||||
@media screen and (prefers-color-scheme: light) {
|
.cl-secondary {
|
||||||
:root {
|
/* You can replace the base-tint on a per-assignment basis, though one tint per context is usual */
|
||||||
--cl-bg: var(--cl-md-100);
|
--cl-fg: var(--cl-1-8);
|
||||||
--cl-bg-mid: var(--cl-md-200);
|
--cl-bg: var(--cl-1-2);
|
||||||
--cl-bg-low: var(--cl-md-300);
|
/* Just shift up all non-fg colors to create a lower-contrast/importance context */
|
||||||
--cl-fg: var(--cl-md-900);
|
--cl-bg-hl: var(--cl-1-3);
|
||||||
}
|
--cl-bg-el: var(--cl-1-4);
|
||||||
|
|
||||||
|
/* Set Default Colors */
|
||||||
|
background-color: var(--cl-bg);
|
||||||
|
color: var(--cl-fg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,16 +14,11 @@ button, .button {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
background-color: var(--cl-bg-low);
|
|
||||||
}
|
}
|
||||||
.button > svg, button > svg {
|
.button > svg, button > svg {
|
||||||
min-width: 1.5rem;
|
min-width: 1.5rem;
|
||||||
min-height: 1.5rem;
|
min-height: 1.5rem;
|
||||||
}
|
}
|
||||||
.button:hover, button:hover {
|
|
||||||
background-color: var(--cl-bg-mid);
|
|
||||||
}
|
|
||||||
|
|
||||||
form {
|
form {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
@ -31,29 +26,21 @@ form {
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
|
|
||||||
background-color: var(--cl-bg-low);
|
|
||||||
}
|
}
|
||||||
form > :is(button, .button, h1) {
|
form > :is(button, .button, h1) {
|
||||||
grid-column: 1 / 3;
|
grid-column: 1 / 3;
|
||||||
}
|
}
|
||||||
form button, form .button {
|
|
||||||
background-color: var(--cl-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
}
|
}
|
||||||
thead {
|
|
||||||
background-color: var(--cl-bg-low);
|
|
||||||
}
|
|
||||||
th:hover {
|
th:hover {
|
||||||
background-color: var(--cl-bg-mid);
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
th, td {
|
th, td {
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
border: 0.125rem solid var(--cl-bg-mid);
|
border: 0.125rem solid var(--cl-fg);
|
||||||
}
|
}
|
||||||
th > *{
|
th > *{
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
@ -62,14 +49,35 @@ th > *{
|
||||||
th svg {
|
th svg {
|
||||||
height: 1rem;
|
height: 1rem;
|
||||||
}
|
}
|
||||||
tbody tr:nth-child(even) {
|
|
||||||
background-color: var(--cl-bg-mid)
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-bar {
|
.search-bar {
|
||||||
display: block;
|
display: block;
|
||||||
padding: 0.4rem;
|
padding: 0.4rem;
|
||||||
background-color: var(--cl-bg-low);
|
|
||||||
color: inherit;
|
|
||||||
border: 1px solid var(--cl-fg);
|
border: 1px solid var(--cl-fg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Coloring */
|
||||||
|
button, .button {
|
||||||
|
background-color: var(--cl-bg-el);
|
||||||
|
}
|
||||||
|
.button:hover, button:hover {
|
||||||
|
background-color: var(--cl-bg-hl);
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
background-color: var(--cl-bg-el);
|
||||||
|
border: 1px solid var(--cl-fg);
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
background-color: var(--cl-bg-el);
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr:hover, th:hover {
|
||||||
|
background-color: var(--cl-bg-hl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Button Background Exception for Nav Menu */
|
||||||
|
.nav-body > button, .button {
|
||||||
|
background-color: var(--cl-bg);
|
||||||
|
}
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { apiCall } from "../api";
|
import { apiCall } from "../api";
|
||||||
|
import Multiselect from 'vue-multiselect';
|
||||||
|
|
||||||
async function doShit(){
|
async function doShit(){
|
||||||
apiCall("Firewall.GetForwardRules", {});
|
apiCall("Firewall.GetForwardRules", {});
|
||||||
}
|
}
|
||||||
|
let value = $ref("");
|
||||||
|
let options = [{ name: 'Vue.js', code: 'vu' },
|
||||||
|
{ name: 'Javascript', code: 'js' },
|
||||||
|
{ name: 'Open Source', code: 'os' }];
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -12,7 +17,8 @@ async function doShit(){
|
||||||
<PageHeader title="Dashboard">
|
<PageHeader title="Dashboard">
|
||||||
<button @click="doShit">Example Buttons</button>
|
<button @click="doShit">Example Buttons</button>
|
||||||
</PageHeader>
|
</PageHeader>
|
||||||
|
<multiselect v-model="value" placeholder="Search" label="name" track-by="code" :options="options" :multiple="true"></multiselect>
|
||||||
This is the main page, currently written in markdown because that's *pog*.
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style src="vue-multiselect/dist/vue-multiselect.css"></style>
|
Loading…
Add table
Reference in a new issue