@hostlink/nuxt-light 1.1.8 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -194,16 +194,16 @@ onMounted(() => {
194
194
  <q-form ref="form1">
195
195
  <div class="q-gutter-sm">
196
196
  <l-input v-model.trim="data.username" label="Username" :rules="[v => !!v || $t('Username is required')]"
197
- clearable :outlined="false" stackLabel/>
197
+ clearable :outlined="false" stackLabel autocomplete="username" />
198
198
  <l-input v-model="data.password" label="Password" type="password" clearable show-password stackLabel
199
- :rules="[v => !!v || $t('Password is required')]" @keydown.enter.prevent="submit" :outlined="false" />
199
+ :rules="[v => !!v || $t('Password is required')]" @keydown.enter.prevent="submit" :outlined="false" autocomplete="current-password" />
200
200
  <l-input v-if="twoFactorAuthentication" v-model="data.code" label="2FA code" required type="text" clearable>
201
201
  </l-input>
202
202
  </div>
203
203
  </q-form>
204
204
  </q-card-section>
205
205
  <q-card-actions>
206
- <l-btn label="Login" outline rounded color="primary" icon="sym_o_login" @click="submit" />
206
+ <l-btn label="Login" outline rounded color="primary" icon="sym_o_login" @click="submit"/>
207
207
  <l-btn v-if="hasBioLogin" outline rounded color="primary" icon="sym_o_fingerprint" @click="bioLogin" />
208
208
  <l-btn label="Forget password" outline rounded color="primary" icon="sym_o_lock_reset" @click="forgetPassword" />
209
209
  </q-card-actions>
@@ -3,7 +3,6 @@ import { ref } from 'vue'
3
3
  const props = defineProps(["value", "dense"])
4
4
  const menus = ref(null);
5
5
 
6
-
7
6
  const expansion = ref(null);
8
7
 
9
8
  const onShowChild = (menu) => {
@@ -28,7 +27,7 @@ defineExpose({
28
27
  </script>
29
28
 
30
29
  <style scoped>
31
- .menu-list .q-item{border-radius:24px 24px 24px 24px}.menu-list .q-router-link--exact-active{background:linear-gradient(118deg,var(--q-primary),rgba(115,103,240,.7));color:#fff}
30
+ .menu-list .q-item{border-radius:12px 12px 12px 12px}.menu-list .q-router-link--exact-active{background:linear-gradient(118deg,var(--q-primary),rgba(115,103,240,.7));color:#fff}
32
31
  </style>
33
32
  <template>
34
33
  <q-expansion-item v-if="value.children?.length > 0" :label="$t(value.label)" :icon="value.icon" :dense="dense"
@@ -39,7 +38,9 @@ defineExpose({
39
38
  </q-list>
40
39
  </q-expansion-item>
41
40
  <q-list v-else class="menu-list" :dense="dense">
42
- <q-item v-ripple :to="value.to">
41
+ <q-separator v-if="value.type == 'separator'" :spaced="value.spaced" />
42
+ <q-item-label header v-if="value.type=='header'">{{ value.label }}</q-item-label>
43
+ <q-item v-ripple :to="value.to" v-if="!value.type" >
43
44
  <q-item-section avatar>
44
45
  <q-icon :name="value.icon" />
45
46
  </q-item-section>
@@ -2,10 +2,10 @@
2
2
  import { computed } from "vue"
3
3
 
4
4
  export interface LSmallBoxProps {
5
- title: string;
6
- subtitle: string;
7
- icon: string;
8
- color: 'red' | 'pink' | 'purple' | 'deep-purple' | 'indigo' | 'blue' | 'light-blue' | 'cyan' | 'teal' | 'green' | 'light-green' | 'lime' | 'yellow' | 'amber' | 'orange' | 'deep-orange' | 'brown' | 'grey' | 'blue-grey'
5
+ title?: string;
6
+ subtitle?: string;
7
+ icon?: string;
8
+ color?: 'red' | 'pink' | 'purple' | 'deep-purple' | 'indigo' | 'blue' | 'light-blue' | 'cyan' | 'teal' | 'green' | 'light-green' | 'lime' | 'yellow' | 'amber' | 'orange' | 'deep-orange' | 'brown' | 'grey' | 'blue-grey'
9
9
  }
10
10
 
11
11
  const props = withDefaults(defineProps<LSmallBoxProps>(), {
@@ -37,13 +37,15 @@ const localValue = computed({
37
37
  }
38
38
  })
39
39
 
40
- const color = light.getStyle("color");
40
+
41
41
 
42
42
  </script>
43
43
 
44
44
  <template>
45
45
  <l-card>
46
- <q-tabs class="text-grey" :active-color="color" :indicator-color="color" align="justify" v-model="localValue">
46
+
47
+ <q-tabs class="text-grey" :active-color="$light.color" :indicator-color="$light.color" align="justify"
48
+ v-model="localValue">
47
49
  <q-tab v-for="tab in tabContents" :label="$t(tab.label)" :name="tab.name"></q-tab>
48
50
  </q-tabs>
49
51
  <q-tab-panels v-model="localValue">
@@ -0,0 +1,29 @@
1
+ <script setup lang="ts">
2
+ import { model, q } from "#imports";
3
+ const props = defineProps(['id']);
4
+ </script>
5
+ <template>
6
+ <div>
7
+ <l-table row-key="eventlog_id" sort-by="eventlog_id:desc"
8
+ :columns="model('EventLog').columns(['eventlog_id', 'class', 'id', 'action', 'created_time'])" @request="async (req) => {
9
+ const a = {
10
+ listUser: {
11
+ __args: {
12
+ filters: {
13
+ user_id: props.id
14
+ }
15
+ },
16
+ data: {
17
+ __args: {
18
+ limit: 1
19
+ },
20
+ eventLog: req.gql
21
+ }
22
+ }
23
+ }
24
+
25
+ let resp = await q(a);
26
+ req.setData(resp.listUser.data[0].eventLog)
27
+ }" />
28
+ </div>
29
+ </template>
@@ -0,0 +1,79 @@
1
+ <script setup lang="ts">
2
+
3
+ import { model } from "#imports";
4
+ const props = defineProps(['id']);
5
+
6
+ const obj = await model('User').get({ user_id: props.id }, ["user_id", "username", "first_name", "last_name", "email", "phone", "roles", 'status', 'join_date'])
7
+
8
+ </script>
9
+ <template>
10
+ <l-card class="q-mb-md">
11
+ <q-card-section>
12
+ <l-row>
13
+ <l-col md="5">
14
+ <q-list dense separator>
15
+ <q-item>
16
+ <q-item-section>
17
+ <q-item-label>{{ $t('Username') }}</q-item-label>
18
+ </q-item-section>
19
+ <q-item-section>{{ obj.username }}</q-item-section>
20
+ </q-item>
21
+ <q-item>
22
+ <q-item-section>
23
+ <q-item-label>{{ $t('First name') }}</q-item-label>
24
+ </q-item-section>
25
+ <q-item-section>{{ obj.first_name }}</q-item-section>
26
+ </q-item>
27
+ <q-item>
28
+ <q-item-section>
29
+ <q-item-label>{{ $t('Last name') }}</q-item-label>
30
+ </q-item-section>
31
+ <q-item-section>{{ obj.last_name }}</q-item-section>
32
+ </q-item>
33
+ <q-item>
34
+ <q-item-section>
35
+ <q-item-label>{{ $t('Email') }}</q-item-label>
36
+ </q-item-section>
37
+ <q-item-section>{{ obj.email }}</q-item-section>
38
+ </q-item>
39
+ <q-item>
40
+ <q-item-section>
41
+ <q-item-label>{{ $t('Phone') }}</q-item-label>
42
+ </q-item-section>
43
+ <q-item-section>{{ obj.phone }}</q-item-section>
44
+ </q-item>
45
+
46
+ <q-item>
47
+ <q-item-section>
48
+ <q-item-label>{{ $t('Roles') }}</q-item-label>
49
+ </q-item-section>
50
+ <q-item-section>
51
+ <div class="q-gutter-xs float-left">
52
+ <q-badge v-for="role in obj.roles" :key="role">{{ role }}</q-badge>
53
+ </div>
54
+ </q-item-section>
55
+ </q-item>
56
+
57
+ <q-item>
58
+ <q-item-section>
59
+ <q-item-label>{{ $t('Status') }}</q-item-label>
60
+ </q-item-section>
61
+ <q-item-section>{{ model('User').columns(["status"])[0].format(obj.status) }}</q-item-section>
62
+ </q-item>
63
+
64
+ <q-item>
65
+ <q-item-section>
66
+ <q-item-label>{{ $t('Join date') }}</q-item-label>
67
+ </q-item-section>
68
+ <q-item-section>{{ obj.join_date }}</q-item-section>
69
+ </q-item>
70
+ </q-list>
71
+
72
+
73
+ </l-col>
74
+ </l-row>
75
+
76
+ </q-card-section>
77
+
78
+ </l-card>
79
+ </template>
@@ -0,0 +1,13 @@
1
+ <script setup lang="ts">
2
+ import { model, q } from "#imports";
3
+ const props = defineProps(['id']);
4
+
5
+ const columns = model('UserLog').columns(["userlog_id", "login_dt", "last_access_time", "logout_dt", "result", "user_agent"]);
6
+ </script>
7
+ <template>
8
+ <div>
9
+ <l-table row-key="userlog_id" sort-by="userlog_id:desc" :columns="columns" @request="async (req) => {
10
+ req.loadObjects('UserLog', { filters: { user_id: props.id } })
11
+ }" />
12
+ </div>
13
+ </template>
@@ -14,7 +14,7 @@ const value = computed({
14
14
  set: (val) => props.context.node.input(val)
15
15
  })
16
16
 
17
- console.log(props.context.node.props.parsedRules);
17
+ //console.log(props.context.node.props.parsedRules);
18
18
 
19
19
  //check required in parsedRules
20
20
  let required = false;
@@ -1,8 +1,51 @@
1
+ declare const app: {
2
+ company: string;
3
+ companyLogo: string;
4
+ color: string;
5
+ theme: string;
6
+ isAdmin: boolean;
7
+ permissions: string[];
8
+ myFavorites: any[];
9
+ setMyFavorites: (favorites: any[]) => void;
10
+ reloadMyFavorites: () => Promise<void>;
11
+ getMyFavorites: () => any[];
12
+ isDarkMode: () => boolean;
13
+ setCompany: (company: string) => void;
14
+ getCompany: () => string;
15
+ setCompanyLogo: (logo: string) => void;
16
+ getCompanyLogo: () => string;
17
+ getVersion: () => any;
18
+ addError: (error: String) => void;
19
+ getErrors: () => String[];
20
+ removeError: (error: String) => void;
21
+ getStyle: (name: String) => any;
22
+ setStyles: (s: Object) => void;
23
+ getStyles: () => {
24
+ [key: string]: any;
25
+ };
26
+ setStyle: (name: String, value: any) => Promise<void>;
27
+ setCurrentRoute: (to: any, from: any) => void;
28
+ getID: () => number | null;
29
+ init: (styles: any) => void;
30
+ isGranted: (right?: string | undefined) => boolean;
31
+ setPermissions: (permissions: string[]) => void;
32
+ };
33
+ declare module 'vue' {
34
+ interface ComponentCustomProperties {
35
+ $light: typeof app;
36
+ }
37
+ }
1
38
  export declare const useLight: () => {
2
39
  company: string;
3
40
  companyLogo: string;
4
41
  color: string;
5
42
  theme: string;
43
+ isAdmin: boolean;
44
+ permissions: string[];
45
+ myFavorites: any[];
46
+ setMyFavorites: (favorites: Array<any>) => void;
47
+ reloadMyFavorites: () => Promise<void>;
48
+ getMyFavorites: () => any[];
6
49
  isDarkMode: () => boolean;
7
50
  setCompany: (company: string) => void;
8
51
  getCompany: () => string;
@@ -15,12 +58,13 @@ export declare const useLight: () => {
15
58
  getStyle: (name: String) => any;
16
59
  setStyles: (s: Object) => void;
17
60
  getStyles: () => {
18
- theme?: String | undefined;
19
- color?: String | undefined;
61
+ [key: string]: any;
20
62
  };
21
63
  setStyle: (name: String, value: any) => Promise<void>;
22
64
  setCurrentRoute: (to: any, from: any) => void;
23
65
  getID: () => number | null;
24
66
  init: (styles: any) => void;
67
+ isGranted: (right?: string) => boolean;
68
+ setPermissions: (permissions: Array<string>) => void;
25
69
  };
26
70
  export * from "./lib";
@@ -1,6 +1,6 @@
1
1
  import packageJson from "../../package.json";
2
2
  import { watch, reactive } from "vue";
3
- import { m } from "./lib/index.mjs";
3
+ import { m, q } from "./lib/index.mjs";
4
4
  const errors = [];
5
5
  let styles = {};
6
6
  let defaultStyle = {
@@ -15,6 +15,28 @@ const app = reactive({
15
15
  companyLogo: "",
16
16
  color: "primary",
17
17
  theme: "light",
18
+ isAdmin: false,
19
+ permissions: Array(),
20
+ myFavorites: Array(),
21
+ setMyFavorites: (favorites) => {
22
+ app.myFavorites = favorites;
23
+ },
24
+ reloadMyFavorites: async () => {
25
+ const data = await q({
26
+ my: {
27
+ myFavorites: {
28
+ my_favorite_id: true,
29
+ label: true,
30
+ path: true,
31
+ icon: true
32
+ }
33
+ }
34
+ });
35
+ app.myFavorites = data.my.myFavorites;
36
+ },
37
+ getMyFavorites: () => {
38
+ return app.myFavorites;
39
+ },
18
40
  isDarkMode: () => {
19
41
  return app.theme == "dark";
20
42
  },
@@ -90,6 +112,18 @@ const app = reactive({
90
112
  watch(() => app.theme, async () => {
91
113
  await app.setStyle("theme", app.theme);
92
114
  });
115
+ },
116
+ isGranted(right) {
117
+ if (right === void 0)
118
+ return true;
119
+ if (app.isAdmin)
120
+ return true;
121
+ if (app.permissions.includes(right))
122
+ return true;
123
+ return false;
124
+ },
125
+ setPermissions(permissions) {
126
+ this.permissions = permissions;
93
127
  }
94
128
  });
95
129
  let currentRoute = null;
@@ -1,4 +1,7 @@
1
1
  {
2
+ "Developer": "開發者",
3
+ "Modules": "模組",
4
+ "Security": "安全",
2
5
  "Password policy": "密碼規則",
3
6
  "Must contain at least {0} characters": "必須包含至少{0}個字元",
4
7
  "contains_symbol": "必須包含符號",
@@ -1,12 +1,25 @@
1
1
  <script setup>
2
2
  import { ref, computed, inject } from 'vue';
3
- import { m, q } from '../../../'
3
+ import { m, q } from '#imports'
4
4
  import { useQuasar } from 'quasar';
5
5
 
6
6
  const quasar = useQuasar();
7
- const menus = ref(await q("appMenus", []));
7
+ const appMenus = await q("appMenus", [])
8
+
9
+
10
+ const menus = ref([
11
+ {
12
+ label: "[Root]",
13
+ uuid: "ROOT",
14
+ children: appMenus.map(m => {
15
+ m.parent = 'ROOT'
16
+ return m
17
+ }),
18
+ type: 'root'
19
+ }
20
+ ]);
8
21
 
9
- const selected = ref(null);
22
+ const selected = ref('ROOT');
10
23
  const tree1 = ref(null)
11
24
 
12
25
  const getUUID = () => {
@@ -20,30 +33,9 @@ const getUUID = () => {
20
33
  }
21
34
 
22
35
  const onReload = async () => {
23
- menus.value = await q("appMenus", []);
36
+ menus.value[0].children = await q("appMenus", []);
24
37
  }
25
38
 
26
- const onAdd = () => {
27
-
28
- quasar.dialog({
29
- title: 'Add Menu',
30
- message: 'Enter menu label',
31
- prompt: {
32
- model: '',
33
- },
34
- cancel: true,
35
- persistent: true,
36
- }).onOk((data) => {
37
- if (data === '') return;
38
-
39
- menus.value.push({
40
- label: data,
41
- uuid: getUUID(),
42
- children: [],
43
- });
44
-
45
- });
46
- }
47
39
  const onAddChild = (node) => {
48
40
 
49
41
  quasar.dialog({
@@ -81,9 +73,10 @@ const onRemove = (node) => {
81
73
  }
82
74
  }
83
75
 
84
- const splitterModel = ref(38)
76
+ const splitterModel = ref(20)
85
77
 
86
78
  const selectedNode = computed(() => {
79
+ if (selected.value == 'ROOT') return menus.value[0];
87
80
  return tree1.value.getNodeByKey(selected.value);
88
81
  });
89
82
  const reloadMenu = inject('reloadMenu')
@@ -98,7 +91,7 @@ const onSave = () => {
98
91
  persistent: true,
99
92
  }).onOk(async () => {
100
93
  if (await m("updateAppMenus", {
101
- data: menus.value
94
+ data: menus.value[0].children
102
95
  })) {
103
96
  quasar.notify({
104
97
  message: 'Menu saved',
@@ -140,20 +133,6 @@ const onMoveConfirm = () => {
140
133
  showMove.value = false;
141
134
 
142
135
  }
143
- const onMoveToRoot = () => {
144
- const selectedNode = tree1.value.getNodeByKey(selected.value);
145
-
146
- //clone selected node
147
- const newNode = JSON.parse(JSON.stringify(selectedNode));
148
- newNode.parent = null;
149
- onRemove(selectedNode);
150
-
151
- //add to target
152
-
153
- menus.value.push(newNode);
154
-
155
- showMove.value = false;
156
- }
157
136
 
158
137
  const getParentNode = (node) => {
159
138
  if (!node.parent) return {
@@ -197,6 +176,34 @@ const onAddChildMenu = (node, type) => {
197
176
  children: [],
198
177
  });
199
178
  }
179
+
180
+ const onAddSeparator = (node) => {
181
+ node.children.push({
182
+ label: '[Separator]',
183
+ uuid: getUUID(),
184
+ parent: node.uuid,
185
+ children: [],
186
+ type: 'separator',
187
+ spaced: true,
188
+ });
189
+
190
+
191
+ }
192
+
193
+ const onAddHeader = (node) => {
194
+ node.children.push({
195
+ label: '[Header]',
196
+ uuid: getUUID(),
197
+ parent: node.uuid,
198
+ children: [],
199
+ type: 'header',
200
+ });
201
+ }
202
+
203
+
204
+ const menusOnly = computed(() => {
205
+ return menus.value.filter((item) => !item.type);
206
+ });
200
207
  </script>
201
208
 
202
209
  <template>
@@ -211,79 +218,109 @@ const onAddChildMenu = (node, type) => {
211
218
  <q-card-actions align="right">
212
219
  <q-btn flat label="Cancel" color="primary" v-close-popup />
213
220
  <q-btn flat label="Move" color="primary" @click="onMoveConfirm" />
214
- <q-btn flat label="Move to root" color="primary" @click="onMoveToRoot" />
221
+ <!-- q-btn flat label="Move to root" color="primary" @click="onMoveToRoot" /-->
215
222
  </q-card-actions>
216
223
  </l-card>
217
224
  </q-dialog>
218
225
 
219
226
  <l-card>
227
+ <q-card-actions v-if="selectedNode">
228
+ <l-btn @click="onSave" label="Save" icon="sym_o_save" />
229
+ <l-btn @click="onReload" label="Reload" icon="sym_o_refresh" />
230
+ <template v-if="selectedNode.type == 'root'">
231
+ <l-btn color="primary" @click="onAddChild(selectedNode)" label="Add" icon="sym_o_add" />
232
+ <l-btn color="primary" @click="onAddHeader(selectedNode)" label="Add Header" icon="sym_o_add" />
233
+ <l-btn color="primary" @click="onAddSeparator(selectedNode)" label="Add Separator" icon="sym_o_add" />
234
+ </template>
235
+
236
+ <template v-else>
237
+ <q-btn-dropdown color="primary" label="Add" icon="sym_o_add">
238
+ <q-list>
239
+ <q-item clickable v-close-popup @click="onAddChild(selectedNode)">
240
+ <q-item-section>
241
+ <q-item-label>Child</q-item-label>
242
+ </q-item-section>
243
+ </q-item>
244
+ <q-item clickable v-close-popup @click="onAddHeader(selectedNode)">
245
+ <q-item-section>
246
+ <q-item-label>Header</q-item-label>
247
+ </q-item-section>
248
+ </q-item>
249
+ <q-item clickable v-close-popup @click="onAddSeparator(selectedNode)">
250
+ <q-item-section>
251
+ <q-item-label>Separator</q-item-label>
252
+ </q-item-section>
253
+ </q-item>
254
+
255
+ </q-list>
256
+ </q-btn-dropdown>
257
+
258
+ <l-btn color="primary" @click="onRemove(selectedNode)" label="Remove" icon="sym_o_remove" />
259
+
260
+
261
+ <l-btn color="primary" @click="onMove(selectedNode)" label="Move" icon="sym_o_move" />
262
+
263
+ <l-btn color="primary" @click="onMoveUp(selectedNode)" label="Up" icon="sym_o_arrow_upward" />
264
+
265
+ <l-btn color="primary" @click="onMoveDown(selectedNode)" label="Down" icon="sym_o_arrow_downward" />
266
+
267
+
268
+ <q-btn-dropdown color="primary" label="Add menus" icon="sym_o_add">
269
+ <q-list>
270
+ <q-item clickable v-close-popup @click="onAddChildMenu(selectedNode, 'list')">
271
+ <q-item-section>
272
+ <q-item-label>List</q-item-label>
273
+ </q-item-section>
274
+ </q-item>
275
+
276
+ <q-item clickable v-close-popup @click="onAddChildMenu(selectedNode, 'add')">
277
+ <q-item-section>
278
+ <q-item-label>Add</q-item-label>
279
+ </q-item-section>
280
+ </q-item>
281
+
282
+ </q-list>
283
+ </q-btn-dropdown>
284
+ </template>
285
+ </q-card-actions>
220
286
  <q-splitter v-model="splitterModel" style="height:680px">
221
287
  <template #before>
222
- <q-card-actions>
223
- <l-btn @click="onAdd" label="Add" icon="sym_o_add" />
224
- <l-btn @click="onReload" label="Reload" icon="sym_o_refresh" />
225
-
226
- <l-btn @click="onSave" label="Save" icon="sym_o_save" />
227
- </q-card-actions>
228
288
 
229
289
  <q-tree :nodes="menus" selected-color="primary" default-expand-all v-model:selected="selected"
230
290
  node-key="uuid" ref="tree1" />
231
291
  </template>
232
292
 
233
293
  <template #after v-if="selected">
234
-
235
- <q-card-actions>
236
- <l-btn outline rounded color="primary" @click="onRemove(selectedNode)" label="Remove"
237
- icon="sym_o_remove" />
238
-
239
- <l-btn outline rounded color="primary" @click="onAddChild(selectedNode)" label="Add Child"
240
- icon="sym_o_add" />
241
-
242
- <l-btn outline rounded color="primary" @click="onMove(selectedNode)" label="Move"
243
- icon="sym_o_move" />
244
-
245
- <l-btn outline rounded color="primary" @click="onMoveUp(selectedNode)" label="Up"
246
- icon="sym_o_arrow_upward" />
247
-
248
- <l-btn outline rounded color="primary" @click="onMoveDown(selectedNode)" label="Down"
249
- icon="sym_o_arrow_downward" />
250
-
251
-
252
- <q-btn-dropdown color="primary" label="Add menus" outline rounded icon="sym_o_add">
253
- <q-list>
254
- <q-item clickable v-close-popup @click="onAddChildMenu(selectedNode, 'list')">
255
- <q-item-section>
256
- <q-item-label>List</q-item-label>
257
- </q-item-section>
258
- </q-item>
259
-
260
- <q-item clickable v-close-popup @click="onAddChildMenu(selectedNode, 'add')">
261
- <q-item-section>
262
- <q-item-label>Add</q-item-label>
263
- </q-item-section>
264
- </q-item>
265
-
266
- </q-list>
267
- </q-btn-dropdown>
268
-
269
-
270
- </q-card-actions>
271
-
272
-
273
294
  <q-card-section>
274
- <div class="q-gutter-md">
275
- <l-input label="Label" v-model="selectedNode.label" />
276
- <l-input label="To" v-model="selectedNode.to" />
277
- <l-input label="Icon" v-model="selectedNode.icon" hint="example: sym_o_add" />
278
- <l-input label="Permission" v-model="selectedNode.permission" />
279
- <l-input label="UUID" v-model="selectedNode.uuid" readonly />
280
- </div>
281
-
282
- <div>
283
- <a href="https://fonts.google.com/icons" target="_blank">Material Icons</a>
284
- </div>
285
-
295
+ <template v-if="!selectedNode.type">
296
+ <div class="q-gutter-md">
297
+ <l-input label="Label" v-model="selectedNode.label" />
298
+ <l-input label="To" v-model="selectedNode.to" />
299
+ <l-input label="Icon" v-model="selectedNode.icon" hint="example: sym_o_add" />
300
+ <l-input label="Permission" v-model="selectedNode.permission" />
301
+ <l-input label="UUID" v-model="selectedNode.uuid" readonly />
302
+ </div>
303
+
304
+ <div>
305
+ <a href="https://fonts.google.com/icons" target="_blank">Material Icons</a>
306
+ </div>
307
+
308
+ </template>
309
+
310
+ <template v-if="selectedNode.type == 'separator'">
311
+ <div class="q-gutter-md">
312
+ <q-checkbox label="Spaced" v-model="selectedNode.spaced" />
313
+
314
+ </div>
315
+ </template>
316
+
317
+ <template v-if="selectedNode.type == 'header'">
318
+ <div class="q-gutter-md">
319
+ <l-input label="Label" v-model="selectedNode.label" />
320
+ </div>
321
+ </template>
286
322
  </q-card-section>
323
+
287
324
  </template>
288
325
 
289
326
  </q-splitter>