mirror of
https://github.com/speatzle/nfsense.git
synced 2025-09-13 07:19:07 +00:00
Linting fixes and form style experiment
- Also updated pnpm on my end for a hopefully clean lockfile
This commit is contained in:
parent
7d2ef675f7
commit
5aec650946
20 changed files with 151 additions and 150 deletions
|
@ -1,6 +1,6 @@
|
|||
// import WebSocketServer from 'ws';
|
||||
import JsonRPC from 'simple-jsonrpc-js';
|
||||
import axios from "axios";
|
||||
import axios from 'axios';
|
||||
import { useToast } from 'vue-toast-notification';
|
||||
|
||||
const $toast = useToast();
|
||||
|
@ -15,24 +15,24 @@ export function setup(_UnauthorizedCallback: () => void) {
|
|||
}
|
||||
|
||||
export async function apiCall(method: string, params: Record<string, any>): Promise<any>{
|
||||
console.debug("Starting API Call...");
|
||||
console.debug('Starting API Call...');
|
||||
try {
|
||||
const result = await jrpc.call(method, params);
|
||||
console.debug("api call result", result);
|
||||
console.debug('api call result', result);
|
||||
return { Data: result, Error: null};
|
||||
} catch (ex: any){
|
||||
if (ex.code === 401) {
|
||||
UnauthorizedCallback();
|
||||
} else {
|
||||
$toast.error(method+ ': ' + ex.message);
|
||||
console.debug("api call epic fail", ex);
|
||||
$toast.error(`${method }: ${ ex.message}`);
|
||||
console.debug('api call epic fail', ex);
|
||||
}
|
||||
return { Data: null, Error: ex};
|
||||
}
|
||||
}
|
||||
|
||||
export async function authenticate(username: string, password: string): Promise<any> {
|
||||
const pResponse = axios.post("/login", { username, password }, {timeout: 10100});
|
||||
const pResponse = axios.post('/login', { username, password }, {timeout: 10100});
|
||||
try {
|
||||
const response = await pResponse;
|
||||
// Dont log this as the user password is inside: console.debug(response);
|
||||
|
@ -43,7 +43,7 @@ export async function authenticate(username: string, password: string): Promise<
|
|||
}
|
||||
|
||||
export async function logout(): Promise<any> {
|
||||
const pResponse = axios.post("/logout", null, {timeout: 10100});
|
||||
const pResponse = axios.post('/logout', null, {timeout: 10100});
|
||||
try {
|
||||
const response = await pResponse;
|
||||
return { data: response.data, error: null};
|
||||
|
@ -53,18 +53,18 @@ export async function logout(): Promise<any> {
|
|||
}
|
||||
|
||||
export async function checkAuthentication() {
|
||||
const pResponse = axios.post("/session", null, {timeout: 10100});
|
||||
const pResponse = axios.post('/session', null, {timeout: 10100});
|
||||
try {
|
||||
const response = await pResponse;
|
||||
const last_hash = window.localStorage.getItem("commit_hash");
|
||||
const last_hash = window.localStorage.getItem('commit_hash');
|
||||
|
||||
if (last_hash) {
|
||||
if (last_hash !== response.data.commit_hash) {
|
||||
console.log("Detected New Backend Version, Reloading...");
|
||||
window.localStorage.removeItem("commit_hash");
|
||||
console.log('Detected New Backend Version, Reloading...');
|
||||
window.localStorage.removeItem('commit_hash');
|
||||
window.location.reload();
|
||||
}
|
||||
} else window.localStorage.setItem("commit_hash", response.data.commit_hash);
|
||||
} else window.localStorage.setItem('commit_hash', response.data.commit_hash);
|
||||
return {auth: 2, error: null};
|
||||
} catch (error: any) {
|
||||
if (error.response.status == 401) {
|
||||
|
|
|
@ -26,9 +26,7 @@ const emit = defineEmits<{
|
|||
(event: 'draggedRow', draggedRow: number, draggedOverRow: number): void,
|
||||
}>();
|
||||
|
||||
if (selection == undefined) {
|
||||
selection = [];
|
||||
}
|
||||
if (!selection) selection = [];
|
||||
|
||||
const displayData = $computed(() => (sortSelf && sortBy !== '')
|
||||
? data?.sort((a, b) => {
|
||||
|
@ -53,8 +51,9 @@ function toggleSorting(columnName: string) {
|
|||
}
|
||||
|
||||
function rowSelection(index: number) {
|
||||
if (!selection) selection = [];
|
||||
if (shiftState) {
|
||||
if (selection.length === 0) {
|
||||
if (!selection?.length) {
|
||||
selection = [index];
|
||||
} else {
|
||||
let last = selection[selection.length-1];
|
||||
|
@ -84,11 +83,11 @@ function rowSelection(index: number) {
|
|||
selection = [index];
|
||||
}
|
||||
}
|
||||
emit("selectionChanged");
|
||||
emit('selectionChanged');
|
||||
}
|
||||
|
||||
function atPath(value: any, path: string): any {
|
||||
for (const segment of path.split(".")) {
|
||||
for (const segment of path.split('.')) {
|
||||
value = value[segment];
|
||||
}
|
||||
return value;
|
||||
|
@ -102,7 +101,7 @@ function dragDropRow() {
|
|||
data.splice(draggedRow, 1);
|
||||
data.splice(draggedOverRow, 0, row);
|
||||
data = data;
|
||||
emit("draggedRow", draggedRow, draggedOverRow);
|
||||
emit('draggedRow', draggedRow, draggedOverRow);
|
||||
}
|
||||
|
||||
// Reset drag data
|
||||
|
@ -137,7 +136,7 @@ function dragDropRow() {
|
|||
@dragenter="() => draggedOverRow = index"
|
||||
@dragend="() => dragDropRow()"
|
||||
:class="{
|
||||
'selected': selection.includes(index),
|
||||
'selected': (selection ?? []).includes(index),
|
||||
'dragged-over-before': index === draggedOverRow && draggedOverRow < draggedRow,
|
||||
'dragged-over-after': index === draggedOverRow && draggedOverRow > draggedRow,
|
||||
}">
|
||||
|
|
|
@ -20,7 +20,7 @@ const emit = defineEmits<{
|
|||
}>();
|
||||
|
||||
async function draggedRow(draggedRow: number, draggedOverRow: number) {
|
||||
emit("draggedRow", draggedRow, draggedOverRow);
|
||||
emit('draggedRow', draggedRow, draggedOverRow);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
@ -31,6 +31,6 @@ async function draggedRow(draggedRow: number, draggedOverRow: number) {
|
|||
<slot/>
|
||||
</PageHeader>
|
||||
<div v-if="loading" >Loading...</div>
|
||||
<NiceTable v-else :columns="columns" v-model:selection="selection" @draggedRow="draggedRow" v-bind="tableProps" :data="data"/>
|
||||
<NiceTable v-else :columns="columns" v-model:selection="selection" @dragged-row="draggedRow" v-bind="tableProps" :data="data"/>
|
||||
</div>
|
||||
</template>
|
|
@ -29,11 +29,11 @@ const props = withDefaults(defineProps<{
|
|||
placeholder?: string,
|
||||
}>(), {
|
||||
modelValue: null,
|
||||
search: "",
|
||||
search: '',
|
||||
options: () => ({}),
|
||||
multiple: false,
|
||||
searchProvider: null,
|
||||
placeholder: "Search...",
|
||||
placeholder: 'Search...',
|
||||
});
|
||||
let { multiple, searchProvider, placeholder } = $(props);
|
||||
|
||||
|
@ -62,14 +62,14 @@ onMounted(() => {
|
|||
await performSearch(unknownKeys);
|
||||
knownKeys = Object.keys(options);
|
||||
unknownKeys = (val as Index[]).filter(key => !knownKeys.includes(key.toString()));
|
||||
for (let key of unknownKeys) console.warn(`Unknown key in DropdownInput:`, key/*, options*/);
|
||||
for (let key of unknownKeys) console.warn('Unknown key in DropdownInput:', key/*, options*/);
|
||||
return modelValue = (val as Index[]).filter(key => knownKeys.includes(key.toString()));
|
||||
}
|
||||
if (!knownKeys.includes(val.toString())) {
|
||||
await performSearch([val]);
|
||||
knownKeys = Object.keys(options);
|
||||
if (!knownKeys.includes(val.toString()))
|
||||
return console.warn(`Unknown key in DropdownInput:`, val/*, options*/);
|
||||
return console.warn('Unknown key in DropdownInput:', val/*, options*/);
|
||||
}
|
||||
modelValue = val;
|
||||
}, { deep: true, immediate: true });
|
||||
|
@ -150,9 +150,9 @@ function toggle(key: any) {
|
|||
|
||||
function handleKeydown(e: KeyboardEvent) {
|
||||
switch (e.key) {
|
||||
case "Backspace":
|
||||
case "Delete":
|
||||
if (!modelValue || search !== "" || !multiple) break;
|
||||
case 'Backspace':
|
||||
case 'Delete':
|
||||
if (!modelValue || search !== '' || !multiple) break;
|
||||
if (navigated === 0) modelValue.pop();
|
||||
else if (navigated > 0) navigated = 0;
|
||||
else {
|
||||
|
@ -161,21 +161,21 @@ function handleKeydown(e: KeyboardEvent) {
|
|||
}
|
||||
modelValue = modelValue;
|
||||
break;
|
||||
case "ArrowUp":
|
||||
case 'ArrowUp':
|
||||
navigated--;
|
||||
if (-navigated > selCount) navigated = 0;
|
||||
e.preventDefault(); // Prevent cursor from moving to the front/back
|
||||
break;
|
||||
case "ArrowDown":
|
||||
case 'ArrowDown':
|
||||
navigated++;
|
||||
if (navigated > Object.entries(options).length) navigated = 0;
|
||||
e.preventDefault(); // Prevent cursor from moving to the front/back
|
||||
break;
|
||||
case "Enter":
|
||||
case 'Enter':
|
||||
if (!expanded) expand();
|
||||
else if (navigated > 0) toggle(Object.entries(options)[navigated-1][0]);
|
||||
break;
|
||||
case "Escape":
|
||||
case 'Escape':
|
||||
if (navigated !== 0) navigated = 0;
|
||||
else expanded = false;
|
||||
break;
|
||||
|
|
|
@ -81,4 +81,7 @@ watchEffect(() => {
|
|||
}
|
||||
.variant { padding: 0.25rem; gap: 0.25rem; }
|
||||
.selected { background-color: var(--cl-bg-sl); }
|
||||
.enum-fields {
|
||||
padding-left: 0px;
|
||||
}
|
||||
</style>
|
|
@ -1,7 +1,7 @@
|
|||
<!-- Wrapper component that sets "multiple" on DropdownInput to true and declares its type to be an array of any -->
|
||||
<script setup lang="ts">
|
||||
import { equals, Index } from "../../util";
|
||||
import { Options, MaybeSearchProvider } from "./DropdownInput.vue";
|
||||
import { equals, Index } from '../../util';
|
||||
import { Options, MaybeSearchProvider } from './DropdownInput.vue';
|
||||
const props = withDefaults(defineProps<{
|
||||
// Two-Way Bindings (v-model)
|
||||
modelValue?: Index[],
|
||||
|
@ -13,10 +13,10 @@ const props = withDefaults(defineProps<{
|
|||
placeholder?: string,
|
||||
}>(), {
|
||||
modelValue: () => [],
|
||||
search: "",
|
||||
search: '',
|
||||
options: () => ({}),
|
||||
searchProvider: null,
|
||||
placeholder: "Search...",
|
||||
placeholder: 'Search...',
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
|
|
@ -62,4 +62,9 @@ watch($$(modelValue), (val) => {
|
|||
label::after {
|
||||
content: ":";
|
||||
}
|
||||
|
||||
label {
|
||||
border-left: 1px solid var(--cl-fg);
|
||||
border-bottom: 1px solid var(--cl-fg);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { isNullish, Index, MaybeIndex } from '../../util';
|
||||
import { Index, MaybeIndex } from '../../util';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
options: Record<Index, {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!-- Wrapper component that sets "multiple" on DropdownInput to false and declares its type to be an Index -->
|
||||
<script setup lang="ts">
|
||||
import { equals, MaybeIndex } from "../../util";
|
||||
import { Options, MaybeSearchProvider } from "./DropdownInput.vue";
|
||||
import { equals, MaybeIndex } from '../../util';
|
||||
import { Options, MaybeSearchProvider } from './DropdownInput.vue';
|
||||
const props = withDefaults(defineProps<{
|
||||
// Two-Way Bindings (v-model)
|
||||
modelValue?: MaybeIndex,
|
||||
|
@ -13,10 +13,10 @@ const props = withDefaults(defineProps<{
|
|||
placeholder?: string,
|
||||
}>(), {
|
||||
modelValue: null,
|
||||
search: "",
|
||||
search: '',
|
||||
options: () => ({}),
|
||||
searchProvider: null,
|
||||
placeholder: "Search...",
|
||||
placeholder: 'Search...',
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
<script setup lang="ts">
|
||||
const { title, noSpacer } = $(withDefaults(defineProps<{
|
||||
const props = withDefaults(defineProps<{
|
||||
title?: string,
|
||||
noSpacer?: boolean,
|
||||
}>(), {
|
||||
title: "",
|
||||
title: '',
|
||||
noSpacer: false,
|
||||
}));
|
||||
});
|
||||
let { title, noSpacer } = $(props);
|
||||
watchEffect(() => useTitle(`${title} - nfSense`));
|
||||
</script>
|
||||
<template>
|
||||
|
|
|
@ -5,11 +5,11 @@ import './global-styles/mlfe.css';
|
|||
import './global-styles/transitions.css';
|
||||
import 'vue-toast-notification/dist/theme-default.css';
|
||||
|
||||
import PillBar from "./components/inputs/PillBar.vue";
|
||||
import TextBox from "./components/inputs/TextBox.vue";
|
||||
import NumberBox from "./components/inputs/NumberBox.vue";
|
||||
import MultilineTextBox from "./components/inputs/MultilineTextBox.vue";
|
||||
import CheckBox from "./components/inputs/CheckBox.vue";
|
||||
import PillBar from './components/inputs/PillBar.vue';
|
||||
import TextBox from './components/inputs/TextBox.vue';
|
||||
import NumberBox from './components/inputs/NumberBox.vue';
|
||||
import MultilineTextBox from './components/inputs/MultilineTextBox.vue';
|
||||
import CheckBox from './components/inputs/CheckBox.vue';
|
||||
import SingleSelect from './components/inputs/SingleSelect.vue';
|
||||
import MultiSelect from './components/inputs/MultiSelect.vue';
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ onMounted(async() => {
|
|||
|
||||
<template>
|
||||
<div>
|
||||
<TableView title="DNAT Rules" :columns="columns" :loading="loading" @draggedRow="draggedRow" v-model:selection="selection" v-model:data="rules" :table-props="{sort:true, sortSelf: true, draggable: true}">
|
||||
<TableView title="DNAT Rules" :columns="columns" :loading="loading" @dragged-row="draggedRow" v-model:selection="selection" v-model:data="rules" :table-props="{sort:true, sortSelf: true, draggable: true}">
|
||||
<button @click="load">Refresh</button>
|
||||
<router-link class="button" to="/firewall/destinationnatrules/edit">Create</router-link>
|
||||
<router-link class="button" :class="{ disabled: selection.length != 1 }" :to="'/firewall/destinationnatrules/edit/' + selection[0]">Edit</router-link>
|
||||
|
|
|
@ -58,7 +58,7 @@ onMounted(async() => {
|
|||
|
||||
<template>
|
||||
<div>
|
||||
<TableView title="Forward Rules" :columns="columns" :loading="loading" @draggedRow="draggedRow" v-model:selection="selection" v-model:data="rules" :table-props="{sort:true, sortSelf: true, draggable: true}">
|
||||
<TableView title="Forward Rules" :columns="columns" :loading="loading" @dragged-row="draggedRow" v-model:selection="selection" v-model:data="rules" :table-props="{sort:true, sortSelf: true, draggable: true}">
|
||||
<button @click="load">Refresh</button>
|
||||
<router-link class="button" to="/firewall/forwardrules/edit">Create</router-link>
|
||||
<router-link class="button" :class="{ disabled: selection.length != 1 }" :to="'/firewall/forwardrules/edit/' + selection[0]">Edit</router-link>
|
||||
|
|
|
@ -59,7 +59,7 @@ onMounted(async() => {
|
|||
|
||||
<template>
|
||||
<div>
|
||||
<TableView title="SNAT Rules" :columns="columns" :loading="loading" @draggedRow="draggedRow" v-model:selection="selection" v-model:data="rules" :table-props="{sort:true, sortSelf: true, draggable: true}">
|
||||
<TableView title="SNAT Rules" :columns="columns" :loading="loading" @dragged-row="draggedRow" v-model:selection="selection" v-model:data="rules" :table-props="{sort:true, sortSelf: true, draggable: true}">
|
||||
<button @click="load">Refresh</button>
|
||||
<router-link class="button" to="/firewall/sourcenatrules/edit">Create</router-link>
|
||||
<router-link class="button" :class="{ disabled: selection.length != 1 }" :to="'/firewall/sourcenatrules/edit/' + selection[0]">Edit</router-link>
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
<script setup lang="ts">
|
||||
import { apiCall } from '../api';
|
||||
|
||||
let links = $ref([]);
|
||||
type Link = {
|
||||
name: string,
|
||||
carrier_state: string,
|
||||
operational_state: string,
|
||||
}
|
||||
|
||||
let links: Link[] = $ref([]);
|
||||
let loading = $ref(false);
|
||||
|
||||
async function load(){
|
||||
|
@ -26,9 +32,11 @@ onMounted(async() => {
|
|||
<div style="overflow-y: auto;">
|
||||
<PageHeader title="Dashboard">
|
||||
</PageHeader>
|
||||
<div v-if="!loading" v-for="(link, index) in links" :key="index">
|
||||
<p>{{ link.name }} {{ link.carrier_state }} {{ link.operational_state }}</p>
|
||||
</div>
|
||||
<template v-if="!loading">
|
||||
<div v-for="(link, index) in links" :key="index">
|
||||
<p>{{ link.name }} {{ link.carrier_state }} {{ link.operational_state }}</p>
|
||||
</div>
|
||||
</template>
|
||||
<div v-else>
|
||||
Loading...
|
||||
</div>
|
||||
|
|
|
@ -26,9 +26,11 @@ onMounted(async () => {
|
|||
<div style="overflow-y: auto;">
|
||||
<PageHeader title="Wireguard Status">
|
||||
</PageHeader>
|
||||
<div v-if="!loading" v-for="(line, index) in status.split('\n')" :key="index">
|
||||
<p>{{ line }}</p>
|
||||
</div>
|
||||
<template v-if="!loading">
|
||||
<div v-for="(line, index) in status.split('\n')" :key="index">
|
||||
<p>{{ line }}</p>
|
||||
</div>
|
||||
</template>
|
||||
<div v-else>
|
||||
Loading...
|
||||
</div>
|
||||
|
|
|
@ -12,7 +12,7 @@ export function equals(a: any, b: any): boolean {
|
|||
}
|
||||
|
||||
export function isNullish(value: any) {
|
||||
return !!(value === null || value === undefined);
|
||||
return (value === null || value === undefined);
|
||||
}
|
||||
|
||||
export type Index = string | number | symbol;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue