Skip to content

Commit 66862ce

Browse files
committed
a
1 parent 6feb4f4 commit 66862ce

15 files changed

+1892
-1593
lines changed

package-lock.json

+1,047-1,280
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+20-18
Original file line numberDiff line numberDiff line change
@@ -3,48 +3,50 @@
33
"version": "0.0.0",
44
"private": true,
55
"scripts": {
6-
"serve": "vite dev",
6+
"dev": "vite -d -d --port 8080",
77
"build": "vite build",
8+
"preview": "vite preview",
89
"lint": "vue-cli-service lint",
9-
"dev": "vite",
10-
"preview": "vite preview"
10+
"test": "vitest run"
1111
},
1212
"dependencies": {
1313
"@pinia/plugin-debounce": "^0.1.0",
14-
"@vueuse/components": "^8.2.5",
15-
"@vueuse/core": "^8.2.5",
14+
"@vueuse/components": "^9.1.0",
15+
"@vueuse/core": "^9.1.0",
1616
"clipboard": "^2.0.11",
1717
"dayjs": "^1.11.4",
18-
"dompurify": "^2.3.6",
18+
"dompurify": "^2.3.10",
1919
"mark.js": "^8.11.1",
20-
"marked": "^4.0.12",
21-
"pinia": "^2.0.13",
20+
"marked": "^4.0.18",
21+
"pinia": "^2.0.18",
2222
"v-network-graph": "^0.6.5",
23-
"vue": "^3.2.25",
24-
"vue-router": "^4.0.14",
23+
"vue": "^3.2.37",
24+
"vue-router": "^4.1.3",
2525
"vue3-json-viewer": "^2.2.2",
26-
"webfontloader": "^1.0.0"
26+
"webfontloader": "^1.6.28"
2727
},
2828
"devDependencies": {
2929
"@types/dompurify": "^2.3.3",
3030
"@types/marked": "^4.0.3",
3131
"@types/node": "^18.6.4",
3232
"@typescript-eslint/eslint-plugin": "^5.21.0",
33+
"@vicons/fluent": "^0.12.0",
3334
"@vicons/material": "^0.12.0",
34-
"@vitejs/plugin-vue": "^2.3.0",
35+
"@vicons/tabler": "^0.12.0",
36+
"@vitejs/plugin-vue": "^2.3.3",
3537
"@vue/cli-plugin-eslint": "~5.0.0",
3638
"@vue/compiler-sfc": "^3.2.31",
37-
"eslint": "^7.32.0",
39+
"eslint": "^8.21.0",
3840
"eslint-config-prettier": "^8.5.0",
3941
"eslint-plugin-prettier": "^4.0.0",
40-
"eslint-plugin-vue": "^8.0.3",
41-
"naive-ui": "^2.28.2",
42+
"eslint-plugin-vue": "^9.3.0",
43+
"naive-ui": "^2.32.1",
4244
"prettier": "2.7.1",
4345
"sass": "^1.38.0",
44-
"sass-loader": "^10.0.0",
46+
"sass-loader": "^13.0.2",
4547
"vfonts": "^0.0.3",
46-
"vite": "^2.9.0",
47-
"vite-plugin-eslint": "^1.6.0",
48+
"vite": "^2.9.14",
49+
"vite-plugin-eslint": "^1.7.0",
4850
"vitest": "^0.21.0"
4951
}
5052
}

src/App.vue

+2-17
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,6 @@
44
:theme-overrides="{ common: { fontWeightStrong: '600' } }"
55
:theme="store.dark ? darkTheme : lightTheme"
66
>
7-
<!-- <n-layout class="root-layout" has-sider>
8-
<n-layout-sider
9-
bordered
10-
show-trigger="arrow-circle"
11-
collapse-mode="width"
12-
:collapsed-width="120"
13-
:width="240"
14-
content-style="padding: 24px;"
15-
>a</n-layout-sider
16-
> -->
177
<n-layout position="absolute">
188
<n-layout-header
199
bordered
@@ -25,8 +15,6 @@
2515
<n-icon size="24" style="padding-top: 6px"><RadarRound /></n-icon>
2616
<span style="font-size: 24px">{{ store.topo.name }}</span>
2717
</n-space>
28-
<!-- <n-text tag="div" class="ui-logo" :depth="1"> </n-text> -->
29-
<!--v-spacer />-->
3018

3119
<n-space justify="end">
3220
<div id="mtoolbar"></div>
@@ -74,7 +62,6 @@
7462
</n-space>
7563
</n-layout-header>
7664

77-
<!-- v-if ensures router views only visible after store initialized (options loaded) -->
7865
<n-layout-content
7966
native-scrollbar
8067
position="absolute"
@@ -112,8 +99,6 @@ import {
11299
NAvatar,
113100
} from "naive-ui";
114101
115-
//import { IMe } from "@/componen ts/types";
116-
117102
import { useMainStore, message } from "@/stores/mainStore";
118103
import { useRoute, useRouter } from "vue-router";
119104
import { useWebSocket } from "@vueuse/core";
@@ -123,7 +108,7 @@ import { wsTemplateBus, wsRxBus, wsTxBus } from "@/utils/eventbus";
123108
124109
const store = useMainStore();
125110
126-
/*** websocket to eventbus handlers */
111+
/** websocket to eventbus handlers */
127112
const { status, data, send, open } = useWebSocket<string>(ws_uri, {
128113
heartbeat: {
129114
message: '{"code":1}',
@@ -137,7 +122,7 @@ wsTxBus.on((tx) => {
137122
send(JSON.stringify(tx));
138123
});
139124
140-
// on any data change, trnasmit the message on the Rx bus or the template bus
125+
// on any data change, transmit the message on the Rx bus or the template bus
141126
watch(data, (msg) => {
142127
if (!msg) return;
143128
const m: WsMessage = JSON.parse(msg);

src/components/ce_control.vue

+156
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
<template>
2+
<n-card title="Clab Config Engine" closable @close="close">
3+
<template #header-extra>
4+
<j-switch v-model:value="showTemplates">
5+
<template #tooltip> Show/hide available templates </template>
6+
<n-icon :component="DescriptionOutlined" />
7+
</j-switch>
8+
</template>
9+
<div v-if="showTemplates">
10+
<h4>Available templates</h4>
11+
<n-table striped size="small">
12+
<thead>
13+
<tr>
14+
<th>Template</th>
15+
<th v-for="(n, i) in roles" :key="`r${i}`" class="cen">
16+
{{ n }}
17+
</th>
18+
</tr>
19+
</thead>
20+
<tbody>
21+
<tr v-for="(rols, name) in templates" :key="name">
22+
<td>{{ name }}</td>
23+
<td v-for="(r, i) in roles" :key="`${name}_${i}`" class="cen">
24+
<n-popover v-if="rols[r]" trigger="hover">
25+
<template #trigger>
26+
<n-icon
27+
:component="
28+
getT(name, r).shadow.length
29+
? LibraryAddCheckOutlined
30+
: CheckBoxOutlined
31+
"
32+
size="18px"
33+
/>
34+
</template>
35+
36+
<p>
37+
Template file:
38+
<span class="fn">
39+
&hellip;/{{ getT(name, r).p }}/{{ getT(name, r).name }}
40+
</span>
41+
</p>
42+
<p v-if="getT(name, r).shadow.length">
43+
Shadows
44+
<span class="fn">
45+
&hellip;/{{ getT(name, r).shadow.join(", ") }}/
46+
</span>
47+
</p>
48+
<n-ellipsis :line-clamp="5">
49+
<pre>{{ getT(name, r).value }}</pre>
50+
</n-ellipsis>
51+
</n-popover>
52+
</td>
53+
</tr>
54+
</tbody>
55+
</n-table>
56+
</div>
57+
<!-- <li v-for="(rols, name) in templates" :key="name">
58+
name:{{ name }}: {{ rols }}
59+
</li> -->
60+
<n-input v-model:value="value" type="text" placeholder="Basic Input">
61+
</n-input>
62+
<n-button @click="exec"> run </n-button>
63+
</n-card>
64+
</template>
65+
66+
<script setup lang="ts">
67+
import { ref, defineEmits, computed } from "vue";
68+
import {
69+
NCard,
70+
NIcon,
71+
NPopover,
72+
NTable,
73+
NEllipsis,
74+
NInput,
75+
NButton,
76+
} from "naive-ui";
77+
import { useMainStore } from "@/stores/mainStore";
78+
import JSwitch from "@/components/j_switch.vue";
79+
import {
80+
LibraryAddCheckOutlined,
81+
CheckBoxOutlined,
82+
DescriptionOutlined,
83+
} from "@vicons/material";
84+
85+
import { ceTemplateName } from "@/utils/helpers";
86+
import { useLocalStorage } from "@vueuse/core";
87+
import { wsSend } from "@/utils/eventbus";
88+
import { WsMsgCodes } from "@/utils/types";
89+
90+
const store = useMainStore();
91+
92+
const emit = defineEmits(["update:close"]);
93+
const value = ref("");
94+
const visible = ref(true);
95+
const showTemplates = useLocalStorage("showTemplates", true);
96+
97+
const templates = computed(() => {
98+
const roles = {} as Record<string, Record<string, boolean>>;
99+
Object.keys(store.templateFiles)
100+
.sort()
101+
.forEach((fn) => {
102+
const tn = ceTemplateName(fn);
103+
if (!(tn.name in roles)) {
104+
roles[tn.name] = {} as Record<string, boolean>;
105+
}
106+
roles[tn.name][tn.role] = true;
107+
});
108+
return roles;
109+
});
110+
111+
const roles = computed(() => {
112+
const r = new Set<string>();
113+
Object.keys(store.templateFiles).forEach((fn) => {
114+
const tn = ceTemplateName(fn);
115+
r.add(tn.role);
116+
});
117+
return [...r].sort();
118+
});
119+
120+
function getT(name: string, role: string) {
121+
const n = `${name}__${role}.tmpl`;
122+
return n in store.templateFiles
123+
? store.templateFiles[n]
124+
: {
125+
name: n,
126+
p: "",
127+
value: "",
128+
shadow: [],
129+
};
130+
}
131+
132+
function exec() {
133+
console.log("run");
134+
wsSend({
135+
code: WsMsgCodes.config_commit,
136+
// payload: { cmd: value.value },
137+
});
138+
}
139+
140+
function close() {
141+
emit("update:close", false);
142+
visible.value = false;
143+
}
144+
</script>
145+
146+
<style>
147+
span.fn {
148+
/*border: 1px solid black;*/
149+
background-color: aliceblue;
150+
padding: 4px;
151+
}
152+
td.cen,
153+
th.cen {
154+
text-align: center;
155+
}
156+
</style>

src/components/j_switch.vue

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<template>
2+
<n-popover v-if="hasSlot('tooltip')" trigger="hover">
3+
<template #trigger>
4+
<n-button
5+
size="small"
6+
type="primary"
7+
strong
8+
:secondary="props.value"
9+
:tertiary="!props.value"
10+
round
11+
@click="toggle"
12+
>
13+
<slot />
14+
</n-button>
15+
</template>
16+
<slot name="tooltip"></slot>
17+
</n-popover>
18+
19+
<n-button
20+
v-else
21+
size="small"
22+
:strong="props.value"
23+
:secondary="props.value"
24+
:dashed="!props.value"
25+
@click="toggle"
26+
>
27+
<slot />
28+
</n-button>
29+
</template>
30+
31+
<script setup lang="ts">
32+
import { defineProps, withDefaults, defineEmits, useSlots } from "vue";
33+
import { NButton, NPopover } from "naive-ui";
34+
35+
export interface PropDef {
36+
value: boolean;
37+
}
38+
const props = withDefaults(defineProps<PropDef>(), {});
39+
40+
const emit = defineEmits(["update:value"]);
41+
42+
function toggle() {
43+
emit("update:value", !props.value);
44+
}
45+
46+
const slots = useSlots();
47+
const hasSlot = (name: string) => {
48+
return !!slots[name];
49+
};
50+
</script>

0 commit comments

Comments
 (0)