mirror of
https://github.com/speatzle/nfsense.git
synced 2025-05-11 02:48:21 +00:00
Small Refactor Pass
- Various transitions away from defineModel - Fixed ChecBox - Reworked PillBar - Made it a bit smaller - Now accepts either an object or array with keys - Moved Index type to util and added MaybeIndex
This commit is contained in:
parent
53fca4f340
commit
b24bfe626e
6 changed files with 58 additions and 56 deletions
|
@ -1,10 +1,17 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
const props = withDefaults(defineProps<{
|
||||||
|
modelValue: boolean
|
||||||
|
}>(), {
|
||||||
|
modelValue: false,
|
||||||
|
});
|
||||||
|
|
||||||
const props = defineModel<{
|
const emit = defineEmits<{
|
||||||
modelValue: boolean,
|
(e: 'update:modelValue', value: boolean): void,
|
||||||
}>();
|
}>();
|
||||||
let { modelValue } = $(props);
|
|
||||||
|
|
||||||
|
let modelValue = $ref(false);
|
||||||
|
watch(() => props.modelValue, (val) => { if (val !== modelValue) modelValue = val; });
|
||||||
|
watch($$(modelValue), (val) => emit('update:modelValue', val));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
<!-- Base component that implements selecting single and multiple values from a list in a type-unsafe manner -->
|
<!-- Base component that implements selecting single and multiple values from a list in a type-unsafe manner -->
|
||||||
<script lang="ts">
|
|
||||||
export type Index = string | number | symbol;
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { equals, isNullish } from '../../util';
|
import { equals, isNullish, Index } from '../../util';
|
||||||
// --- Prop setup ---
|
// --- Prop setup ---
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
// Two-Way Bindings (v-model)
|
// Two-Way Bindings (v-model)
|
||||||
|
@ -33,10 +29,10 @@ const emit = defineEmits<{
|
||||||
// Hook up two-way bindings
|
// Hook up two-way bindings
|
||||||
let modelValue = $ref(multiple ? props.modelValue ?? [] : props.modelValue);
|
let modelValue = $ref(multiple ? props.modelValue ?? [] : props.modelValue);
|
||||||
watch(() => props.modelValue, (val: any) => { if (!equals(val, modelValue)) modelValue = val; }, { deep: true });
|
watch(() => props.modelValue, (val: any) => { if (!equals(val, modelValue)) modelValue = val; }, { deep: true });
|
||||||
watch($$(modelValue), (val: any) => { if(!equals(val, props.modelValue)) emit('update:modelValue', modelValue); }, { deep: true });
|
watch($$(modelValue), (val: any) => emit('update:modelValue', modelValue), { deep: true });
|
||||||
let search = $ref(props.search);
|
let search = $ref(props.search);
|
||||||
watch(() => props.search, (val: string) => { if (!equals(val, search)) search = val; }, { deep: true });
|
watch(() => props.search, (val: string) => { if (!equals(val, search)) search = val; }, { deep: true });
|
||||||
watch($$(search), (val) => { if(!equals(val, props.search)) emit('update:search', search); }, { deep: true });
|
watch($$(search), (val) => emit('update:search', search), { deep: true });
|
||||||
|
|
||||||
// --- Everything Else ---
|
// --- Everything Else ---
|
||||||
let expanded = $ref(false);
|
let expanded = $ref(false);
|
||||||
|
|
|
@ -1,41 +1,39 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { isNullish, Index, MaybeIndex } from '../../util';
|
||||||
|
|
||||||
const props = defineModel<{
|
const props = withDefaults(defineProps<{
|
||||||
options: {
|
options: Record<Index, {
|
||||||
name: string,
|
display?: string,
|
||||||
key: string,
|
icon?: Component,
|
||||||
icon: Component,
|
}>,
|
||||||
}[],
|
modelValue: MaybeIndex,
|
||||||
modelValue: number | string,
|
}>(), {
|
||||||
useIndex: boolean,
|
options: () => ({}),
|
||||||
|
});
|
||||||
|
const { options } = $(props);
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'update:modelValue', value: MaybeIndex): void,
|
||||||
}>();
|
}>();
|
||||||
let { options, modelValue, useIndex } = $(props);
|
|
||||||
|
|
||||||
function setSelection(option: any, index: number){
|
let modelValue: MaybeIndex = $ref(null);
|
||||||
if (useIndex) {
|
watch(() => props.modelValue, (val) => { if (val !== modelValue) modelValue = val; });
|
||||||
modelValue = index
|
watch($$(modelValue), (val) => emit('update:modelValue', val));
|
||||||
} else {
|
|
||||||
modelValue = option.key
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(async() => {
|
onMounted(async() => {
|
||||||
if (modelValue === undefined) {
|
if (isNullish(modelValue)) {
|
||||||
if (useIndex) {
|
const entries = Object.entries(options);
|
||||||
modelValue = 0
|
modelValue = entries.length > 0
|
||||||
} else {
|
? entries[0][0]
|
||||||
modelValue = options[0].key
|
: null;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<button class="option" v-for="(option, index) in options" :key="index" :class="{selected: modelValue == index || modelValue == option.key}" @click="setSelection(option, index)">
|
<button class="option" v-for="[index, option] of Object.entries(options)" :key="index" :class="{selected: modelValue === index}" @click="() => modelValue = index">
|
||||||
<i class="material-icons" v-if="option.icon">{{ option.icon }}</i>
|
<component :is="option.icon"/>
|
||||||
{{ option.name }}
|
{{ option.display }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -43,9 +41,8 @@ onMounted(async() => {
|
||||||
<style scoped>
|
<style scoped>
|
||||||
div {
|
div {
|
||||||
flex-flow: nowrap;
|
flex-flow: nowrap;
|
||||||
|
gap: 0.25rem;
|
||||||
}
|
}
|
||||||
|
button { padding: 0.25rem; gap: 0.25rem; }
|
||||||
.selected {
|
.selected { background-color: var(--cl-bg-sl); }
|
||||||
background-color: var(--cl-bg-sl);
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
|
@ -1,10 +1,9 @@
|
||||||
<!-- Wrapper component that sets "multiple" on DropdownInput to false and declares its type to be an Index -->
|
<!-- Wrapper component that sets "multiple" on DropdownInput to false and declares its type to be an Index -->
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Index } from "./DropdownInput.vue";
|
import { equals, Index, MaybeIndex } from "../../util";
|
||||||
import { equals } from "../../util";
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
// Two-Way Bindings (v-model)
|
// Two-Way Bindings (v-model)
|
||||||
modelValue?: Index | null,
|
modelValue?: MaybeIndex,
|
||||||
search?: string,
|
search?: string,
|
||||||
|
|
||||||
// One-Way Bindings
|
// One-Way Bindings
|
||||||
|
|
|
@ -18,9 +18,9 @@ export const editTypes: { [key: string]: { [key: string]: any } } = {
|
||||||
{
|
{
|
||||||
fields: [
|
fields: [
|
||||||
{ key: "name", label: "Name", as: "TextBox" },
|
{ key: "name", label: "Name", as: "TextBox" },
|
||||||
{ key: "verdict", label: "Verdict", as: "PillBar", props: { options: [{ name: 'Accept', key: 'accept' }, { name: 'Drop', key: 'drop' }, { name: 'Continue', key: 'continue' }] } },
|
{ key: "verdict", label: "Verdict", as: "PillBar", props: { options: { accept: { display: 'Accept' }, drop: { display: 'Drop' }, continue: { display: 'Continue' } } } },
|
||||||
{ key: "counter", label: "Counter", as: "CheckBox", },
|
{ key: "counter", label: "Counter", as: "CheckBox" },
|
||||||
{ key: "comment", label: "Comment", as: "MultilineTextBox", },
|
{ key: "comment", label: "Comment", as: "MultilineTextBox" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -43,7 +43,7 @@ export const editTypes: { [key: string]: { [key: string]: any } } = {
|
||||||
{
|
{
|
||||||
fields: [
|
fields: [
|
||||||
{ key: "name", label: "Name", as: "TextBox", default: "placeholder" },
|
{ key: "name", label: "Name", as: "TextBox", default: "placeholder" },
|
||||||
{ key: "type", label: "Type", as: "PillBar", props: { options: [{ name: 'Hardware', key: 'hardware' }, { name: 'VLAN', key: 'vlan' }, { name: 'Bond', key: 'bond' }, { name: 'Bridge', key: 'bridge' }] } },
|
{ key: "type", label: "Type", as: "PillBar", props: { options: { hardware: { display: 'Hardware' }, vlan: { display: 'VLAN' }, bond: { display: 'Bond' }, bridge: { display: 'Bridge' } } } },
|
||||||
{ key: "hardware_device", label: "Hardware Device", as: "TextBox", enabled: (values: any) => (values["type"] == 'hardware') },
|
{ key: "hardware_device", label: "Hardware Device", as: "TextBox", enabled: (values: any) => (values["type"] == 'hardware') },
|
||||||
{ key: "vlan_parent", label: "VLAN Parent", as: "TextBox", enabled: (values: any) => (values["type"] == 'vlan') },
|
{ key: "vlan_parent", label: "VLAN Parent", as: "TextBox", enabled: (values: any) => (values["type"] == 'vlan') },
|
||||||
{ key: "vlan_id", label: "VLAN ID", as: "NumberBox", props: { min: 1, max: 4094 }, enabled: (values: any) => (values["type"] == 'vlan') },
|
{ key: "vlan_id", label: "VLAN ID", as: "NumberBox", props: { min: 1, max: 4094 }, enabled: (values: any) => (values["type"] == 'vlan') },
|
||||||
|
@ -54,11 +54,11 @@ export const editTypes: { [key: string]: { [key: string]: any } } = {
|
||||||
{
|
{
|
||||||
title: "Addressing",
|
title: "Addressing",
|
||||||
fields: [
|
fields: [
|
||||||
{ key: "addressing_mode", label: "Addressing Mode", as: "PillBar", props: { options: [{ name: 'None', key: 'none' }, { name: 'Static', key: 'static' }, { name: 'DHCP', key: 'dhcp' }] } },
|
{ key: "addressing_mode", label: "Addressing Mode", as: "PillBar", props: { options: { none: { display: 'None' }, static: { display: 'Static' }, dhcp: { display: 'DHCP' } } } },
|
||||||
{ key: "address", label: "Address", as: "TextBox", enabled: (values: any) => (values["addressing_mode"] == 'static') },
|
{ key: "address", label: "Address", as: "TextBox", enabled: (values: any) => (values["addressing_mode"] == 'static') },
|
||||||
{ key: "comment", label: "Comment", as: "MultilineTextBox" },
|
{ key: "comment", label: "Comment", as: "MultilineTextBox" },
|
||||||
],
|
],
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
"staticroutes": {
|
"staticroutes": {
|
||||||
|
@ -71,7 +71,7 @@ export const editTypes: { [key: string]: { [key: string]: any } } = {
|
||||||
sections: [
|
sections: [
|
||||||
{
|
{
|
||||||
fields: [
|
fields: [
|
||||||
{ key: "name", label: "Name", as: "TextBox", },
|
{ key: "name", label: "Name", as: "TextBox" },
|
||||||
{ key: "interface", label: "Interface", as: "TextBox" },
|
{ key: "interface", label: "Interface", as: "TextBox" },
|
||||||
{ key: "gateway", label: "Gateway", as: "TextBox" },
|
{ key: "gateway", label: "Gateway", as: "TextBox" },
|
||||||
{ key: "destination", label: "Destination", as: "TextBox" },
|
{ key: "destination", label: "Destination", as: "TextBox" },
|
||||||
|
|
|
@ -14,3 +14,6 @@ export function equals(a: any, b: any): boolean {
|
||||||
export function isNullish(value: any) {
|
export function isNullish(value: any) {
|
||||||
return !!(value === null || value === undefined);
|
return !!(value === null || value === undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type Index = string | number | symbol;
|
||||||
|
export type MaybeIndex = Index | null;
|
Loading…
Add table
Reference in a new issue