@hostlink/nuxt-light 1.21.1 → 1.21.3

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.
Files changed (34) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +23 -24
  3. package/dist/runtime/components/L/Database/create-table-dialog.vue +72 -0
  4. package/dist/runtime/components/L/System/Setting/modules.vue +6 -44
  5. package/dist/runtime/components/l-dialog-database-field-add.vue +1 -1
  6. package/dist/runtime/components/l-file-upload.vue +7 -3
  7. package/dist/runtime/components/l-file.vue +3 -2
  8. package/dist/runtime/components/l-page.vue +9 -5
  9. package/dist/runtime/formkit/File.vue +2 -2
  10. package/dist/runtime/formkit/Repeater.vue +6 -6
  11. package/dist/runtime/index.d.ts +38 -39
  12. package/dist/runtime/index.js +0 -4
  13. package/dist/runtime/lib/collect.d.ts +3 -0
  14. package/dist/runtime/lib/collect.js +4 -0
  15. package/dist/runtime/lib/getObject.js +1 -1
  16. package/dist/runtime/lib/index.d.ts +1 -0
  17. package/dist/runtime/lib/index.js +1 -0
  18. package/dist/runtime/light.d.ts +8 -8
  19. package/dist/runtime/light.js +6 -6
  20. package/dist/runtime/pages/Role/index.vue +40 -31
  21. package/dist/runtime/pages/System/database/backup.vue +1 -1
  22. package/dist/runtime/pages/System/database/table.vue +161 -50
  23. package/dist/runtime/pages/System/fs.vue +48 -34
  24. package/dist/runtime/pages/System/mailtest.vue +1 -1
  25. package/dist/runtime/pages/System/package.vue +6 -2
  26. package/dist/runtime/pages/System/phpinfo.vue +7 -3
  27. package/dist/runtime/pages/System/setting.vue +1 -2
  28. package/dist/runtime/pages/User/profile.vue +30 -24
  29. package/dist/runtime/pages/User/setting/index.vue +10 -19
  30. package/dist/runtime/pages/User/setting/information.vue +10 -3
  31. package/dist/runtime/pages/User/setting/style.vue +6 -3
  32. package/dist/runtime/pages/User/setting/two-factor-auth.vue +24 -11
  33. package/package.json +2 -3
  34. package/dist/runtime/components/l-file-manager copy.vue +0 -750
@@ -1,23 +1,38 @@
1
1
  <script setup>
2
2
  import { useQuasar } from 'quasar'
3
- import { q, m, notify } from '#imports'
4
- import { ref } from "vue"
3
+ import { q, m, notify, useAsyncData } from '#imports'
5
4
  import { useI18n } from 'vue-i18n';
6
5
  const { t } = useI18n();
7
6
  const qua = useQuasar();
8
- const quasar = useQuasar();
7
+ const { data, refresh } = await useAsyncData('role', async () => {
8
+
9
+ const data = await q({
10
+ app: {
11
+ roles: {
12
+ name: true,
13
+ canDelete: true,
14
+ canUpdate: true,
15
+ children: true,
16
+ user: {
17
+ name: true,
18
+ user_id: true
19
+ }
20
+ },
21
+ listUser: {
22
+ data: {
23
+ user_id: true,
24
+ name: true
25
+ }
26
+ }
27
+ }
28
+ });
29
+ return data.app;
30
+ })
9
31
 
10
- const loadData = async () => {
11
- return await q("listRole", ["name", "canDelete", "canUpdate", "children", {
12
- user: ["name", "user_id"]
13
- }]);
14
- }
15
- const roles = ref(await loadData());
16
- let role_options = roles.value.map(r => ({ label: r.name, value: r.name }))
17
32
 
18
- const users = (await q("listUser", [{
19
- data: ["user_id", "name"]
20
- }])).data;
33
+ let role_options = data.value.roles.map(r => ({ label: r.name, value: r.name }))
34
+
35
+ let users = data.value.listUser.data;
21
36
 
22
37
  const onDelete = async (role) => {
23
38
  //confirm
@@ -28,9 +43,9 @@ const onDelete = async (role) => {
28
43
  persistent: true,
29
44
  }).onOk(async () => {
30
45
 
31
- m("deleteRole", { name: role })
32
- //refresh
33
- roles.value = await loadData();
46
+ await m("deleteRole", { name: role })
47
+ refresh();
48
+
34
49
  });
35
50
 
36
51
  }
@@ -66,8 +81,8 @@ const onRemoveChild = async (value, child) => {
66
81
  //notify
67
82
  notify("Role removed from role")
68
83
 
69
- //refresh
70
- roles.value = await loadData();
84
+ refresh();
85
+
71
86
  }
72
87
 
73
88
  const onAddChild = async (value, child) => {
@@ -79,9 +94,8 @@ const onAddChild = async (value, child) => {
79
94
 
80
95
  //notify
81
96
  notify("Role added to role")
97
+ refresh();
82
98
 
83
- //refresh
84
- roles.value = await loadData();
85
99
  }
86
100
 
87
101
  const onAddUser = async (value, user) => {
@@ -94,8 +108,7 @@ const onAddUser = async (value, user) => {
94
108
  //notify
95
109
  notify("User added to role")
96
110
 
97
- //refresh
98
- roles.value = await loadData();
111
+ refresh();
99
112
  }
100
113
 
101
114
  const onRemoveUser = async (value, user) => {
@@ -104,31 +117,27 @@ const onRemoveUser = async (value, user) => {
104
117
  user_id: user.value.user_id
105
118
 
106
119
  });
107
-
108
120
  //notify
109
121
  notify("User removed from role")
110
-
111
- //refresh
112
- roles.value = await loadData();
122
+ refresh();
113
123
  }
114
124
  </script>
115
125
 
116
126
  <template>
117
127
  <l-page>
118
- <q-table :rows="roles" flat bordered :columns="columns" :rows-per-page-options="[0]" dense>
128
+ <q-table :rows="data.roles" flat bordered :columns="columns" :rows-per-page-options="[0]" dense>
119
129
  <template #body-cell-_can_delete="props">
120
130
  <q-td auto-width>
121
131
  <q-btn v-if="props.row.canDelete" flat round dense icon="sym_o_delete"
122
132
  @click="onDelete(props.row.name)" />
123
-
124
133
  </q-td>
125
134
  </template>
126
135
 
127
136
  <template #body-cell-children="props">
128
137
  <q-td>
129
138
  <q-select :options="role_options" v-model="props.row.children" multiple use-chips dense
130
- @remove="onRemoveChild(props.row.name, $event)" @add="onAddChild(props.row.name, $event)">
131
-
139
+ @remove="onRemoveChild(props.row.name, $event)" @add="onAddChild(props.row.name, $event)"
140
+ :color="$light.color">
132
141
  </q-select>
133
142
  </q-td>
134
143
  </template>
@@ -136,7 +145,7 @@ const onRemoveUser = async (value, user) => {
136
145
  <q-td>
137
146
  <q-select :options="users" v-model="props.row.user" multiple use-chips dense option-label="name"
138
147
  option-value="user_id" @add="onAddUser(props.row.name, $event)"
139
- @remove="onRemoveUser(props.row.name, $event)">
148
+ @remove="onRemoveUser(props.row.name, $event)" :color="$light.color">
140
149
 
141
150
  </q-select>
142
151
  </q-td>
@@ -33,7 +33,7 @@ const onClickDownload = async () => {
33
33
  }
34
34
  </script>
35
35
  <template>
36
- <l-page>
36
+ <l-page title="Database backup">
37
37
  <l-btn label="Download" icon="sym_o_download" @click="onClickDownload"></l-btn>
38
38
  </l-page>
39
39
  </template>
@@ -1,35 +1,34 @@
1
1
  <script setup>
2
- import { api, m, useLight } from '#imports';
3
- import { resolveComponent, ref, reactive } from 'vue';
2
+ import { api, m, useLight, useAsyncData } from '#imports';
3
+ import { resolveComponent, ref, reactive, computed } from 'vue';
4
4
  const light = useLight();
5
5
 
6
- const { system: { database } } = await api.query({
7
- system: {
8
- database: {
9
- table: true,
10
- version: true,
11
- tableStatus: true
12
- }
13
-
14
- }
15
- })
16
-
17
- const tables = ref(database.table);
18
-
19
- const refresh = async () => {
20
- const { system: { database } } = await api.query({
6
+ const { data, refresh } = await useAsyncData('database', async () => {
7
+ const { system } = await api.query({
21
8
  system: {
22
9
  database: {
23
10
  table: true,
24
- version: true
11
+ version: true,
12
+ tableStatus: true
25
13
  }
26
14
  }
27
15
  })
28
- tables.value = database.table;
29
- }
16
+ return system.database;
17
+ })
18
+
19
+ const SYSTEM_TABLES = ["Config", "EventLog", "MailLog", "Permission", "Role", "SystemValue", "Translate", "User", "UserLog", "UserRole"];
20
+
21
+ const custom_tables = computed(() => {
22
+ return data.value.tableStatus.filter(table => !SYSTEM_TABLES.includes(table.Name))
23
+ })
30
24
 
25
+ const systables = computed(() => {
26
+ return data.value.tableStatus.filter(table => SYSTEM_TABLES.includes(table.Name))
27
+ })
31
28
 
32
29
  const field_add = resolveComponent('l-dialog-database-field-add');
30
+
31
+ const table_add = resolveComponent('l-database-create-table-dialog');
33
32
  const add = async (table) => {
34
33
  light.dialog({
35
34
  component: field_add
@@ -37,7 +36,7 @@ const add = async (table) => {
37
36
  //data.name
38
37
  //data.type
39
38
  try {
40
- const addDatabaseField = await m("addDatabaseField", {
39
+ await m("lightDatabaseAddField", {
41
40
  table,
42
41
  field: data.name,
43
42
  type: data.type,
@@ -46,11 +45,11 @@ const add = async (table) => {
46
45
  nullable: data.nullable,
47
46
  autoincrement: data.autoincrement
48
47
  })
48
+
49
49
  light.notify({
50
- type: 'positive',
51
- message: addDatabaseField
50
+ type: "positive",
51
+ message: "Field added successfully"
52
52
  })
53
-
54
53
  refresh();
55
54
 
56
55
  } catch (e) {
@@ -65,7 +64,7 @@ const add = async (table) => {
65
64
 
66
65
  const selected = reactive({});
67
66
 
68
- for (let table of database.table) {
67
+ for (let table of data.value.table) {
69
68
  selected[table.name] = [];
70
69
  }
71
70
 
@@ -79,20 +78,16 @@ const removeField = async (table) => {
79
78
  ok: 'Yes',
80
79
  cancel: 'No'
81
80
  }).onOk(async () => {
82
-
83
-
84
81
  //map selected fields
85
-
86
82
  const fields = selected[table].map(field => field.Field)
87
-
88
83
  try {
89
- const removeDatabaseFields = await m("removeDatabaseFields", {
84
+ await m("lightDatabaseRemoveFields", {
90
85
  table,
91
86
  fields: fields
92
87
  })
93
- lgiht.notify({
88
+ light.notify({
94
89
  type: 'positive',
95
- message: removeDatabaseFields
90
+ message: "Fields removed successfully"
96
91
  })
97
92
 
98
93
  selected[table] = [];
@@ -106,28 +101,144 @@ const removeField = async (table) => {
106
101
  }
107
102
  })
108
103
 
104
+ }
105
+
106
+ const createTable = () => {
107
+ light.dialog({
108
+ component: table_add
109
+ }).onOk(async (data) => {
110
+ try {
111
+ await m("lightDatabaseCreateTable", {
112
+ name: data.name,
113
+ fields: data.fields
114
+ })
115
+ light.notify({
116
+ type: 'positive',
117
+ message: "Table created successfully"
118
+ })
119
+ } catch (e) {
120
+ light.notify({
121
+ type: 'negative',
122
+ message: e.message
123
+ })
124
+ }
125
+ refresh();
126
+ });
127
+ }
128
+
129
+ const selectedTable = ref([]);
130
+
131
+ const removeTable = async () => {
132
+ light.dialog({
133
+ title: 'Remove table',
134
+ message: 'Are you sure you want to remove the selected tables?',
135
+ ok: 'Yes',
136
+ cancel: 'No'
137
+ }).onOk(async () => {
138
+ //map selected fields
139
+ const tables = selectedTable.value.map(table => table.Name)
140
+ try {
141
+ for (let table of tables) {
142
+ await m("lightDatabaseRemoveTable", {
143
+ table
144
+ })
145
+ }
146
+
147
+ } catch (e) {
148
+ light.notify({
149
+ type: 'negative',
150
+ message: e.message
151
+ })
152
+ return;
153
+
154
+ }
155
+
156
+ light.notify({
157
+ type: 'positive',
158
+ message: "Tables removed successfully"
159
+ })
160
+
161
+ selectedTable.value = [];
162
+
163
+ refresh();
164
+ })
165
+ }
166
+
167
+ const truncatTable = async () => {
168
+ light.dialog({
169
+ title: 'Truncate table',
170
+ message: 'Are you sure you want to truncate the selected tables?',
171
+ ok: 'Yes',
172
+ cancel: 'No'
173
+ }).onOk(async () => {
174
+ //map selected fields
175
+ const tables = selectedTable.value.map(table => table.Name)
176
+ try {
177
+ for (let table of tables) {
178
+ await m("lightDatabaseTruncateTable", {
179
+ table
180
+ })
181
+ }
109
182
 
183
+ } catch (e) {
184
+ light.notify({
185
+ type: 'negative',
186
+ message: e.message
187
+ })
188
+ return;
110
189
 
190
+ }
111
191
 
192
+ light.notify({
193
+ type: 'positive',
194
+ message: "Tables truncated successfully"
195
+ })
112
196
 
197
+ selectedTable.value = [];
113
198
 
199
+ refresh();
200
+ })
114
201
  }
115
202
  </script>
116
203
  <template>
117
- <l-page gutter="sm">
204
+ <l-page title="Database">
118
205
  <l-card>
119
206
  <l-list>
120
- <l-item label="Version">{{ database.version }}</l-item>
207
+ <l-item label="Version">{{ data.version }}</l-item>
121
208
  </l-list>
122
209
  </l-card>
123
210
 
124
-
125
211
  <q-card flat bordered>
126
- <q-list class="rounded-borders" separator bordered>
212
+ <q-list separator bordered>
127
213
  <q-expansion-item label="Table Status" dense>
128
- <div class="q-ma-sm">
129
- <q-table :rows="database.tableStatus" hide-pagination flat bordered separator="cell" dense
130
- :rows-per-page-options="[0]">
214
+ <div class="q-ma-sm q-gutter-y-sm">
215
+
216
+ <q-table :rows="custom_tables" hide-pagination flat bordered separator="cell" dense
217
+ :rows-per-page-options="[0]" v-model:selected="selectedTable" selection="multiple"
218
+ row-key="Name" @selection="onSelectionTable">
219
+
220
+ <template #top-left>
221
+ <q-btn icon="sym_o_add" @click="createTable()" round flat size="sm">
222
+ <q-tooltip>Create table</q-tooltip>
223
+ </q-btn>
224
+ <q-btn icon="sym_o_delete" @click="removeTable()" round flat size="sm"
225
+ :disable="selectedTable.length == 0">
226
+ <q-tooltip>Remove table</q-tooltip>
227
+ </q-btn>
228
+
229
+ <q-btn icon="sym_o_scan_delete" @click="truncatTable" round flat size="sm"
230
+ :disable="selectedTable.length == 0">
231
+ <q-tooltip>Truncate table</q-tooltip>
232
+ </q-btn>
233
+
234
+ </template>
235
+ </q-table>
236
+
237
+
238
+
239
+ <q-table :rows="systables" hide-pagination flat bordered separator="cell" dense
240
+ :rows-per-page-options="[0]" row-key="Name" title="System tables">
241
+
131
242
  </q-table>
132
243
  </div>
133
244
  </q-expansion-item>
@@ -135,21 +246,21 @@ const removeField = async (table) => {
135
246
  </q-card>
136
247
 
137
248
  <q-card flat bordered>
138
- <q-list class="rounded-borders" separator bordered>
139
- <q-expansion-item :label="table.name" v-for="table in tables" dense>
140
- <q-toolbar>
141
- <q-btn icon="sym_o_add" @click="add(table.name)" round flat size="sm">
142
- <q-tooltip>Add field</q-tooltip>
143
- </q-btn>
144
- <q-btn icon="sym_o_delete" @click="removeField(table.name)" round flat size="sm"
145
- :disable="selected[table.name].length == 0">
146
- <q-tooltip>Remove field</q-tooltip>
147
- </q-btn>
148
- </q-toolbar>
249
+ <q-list separator bordered>
250
+ <q-expansion-item :label="table.name" v-for="table in data.table" dense>
149
251
  <div class="q-ma-sm">
150
252
  <q-table row-key="Field" separator="cell" dense :rows="table.columns"
151
253
  :rows-per-page-options="[0]" hide-pagination flat bordered selection="multiple"
152
254
  v-model:selected="selected[table.name]">
255
+ <template #top-left>
256
+ <q-btn icon="sym_o_add" @click="add(table.name)" round flat size="sm">
257
+ <q-tooltip>Add field</q-tooltip>
258
+ </q-btn>
259
+ <q-btn icon="sym_o_delete" @click="removeField(table.name)" round flat size="sm"
260
+ :disable="selected[table.name].length == 0">
261
+ <q-tooltip>Remove field</q-tooltip>
262
+ </q-btn>
263
+ </template>
153
264
  </q-table>
154
265
  </div>
155
266
 
@@ -1,14 +1,19 @@
1
1
  <script setup>
2
- import { ref } from 'vue';
3
- import { m, q } from "#imports"
4
- const { app, listFileSystem } = await q({
5
- app: {
6
- driveTypes: true
7
- },
8
- listFileSystem: true
9
- });
10
-
11
- const items = ref(listFileSystem)
2
+ import { ref, computed } from 'vue';
3
+ import { m, q, useAsyncData } from "#imports"
4
+ import { useQuasar } from "#imports"
5
+ const $q = useQuasar()
6
+ const { data: app, refresh } = await useAsyncData(async () => {
7
+ return (await q({
8
+ app: {
9
+ driveTypes: true,
10
+ listFileSystem: true
11
+ }
12
+ })).app;
13
+ })
14
+
15
+
16
+ const items = computed(() => app.value.listFileSystem)
12
17
  const dialog = ref(false)
13
18
  const value = ref({})
14
19
 
@@ -18,27 +23,34 @@ const onSubmit = async (data) => {
18
23
  data: data
19
24
  })
20
25
 
21
- items.value.push(data)
22
26
  dialog.value = false
27
+ refresh()
23
28
  }
24
29
 
25
- const onRemove = async (row) => {
26
- await m("deleteFileSystem", {
27
- name: row.name
28
- })
29
- //reload data
30
+ const onRemove = async (selected) => {
31
+
32
+ //confirm
33
+ $q.dialog({
34
+ title: 'Confirm',
35
+ message: 'Are you sure you want to delete this file system?',
36
+ ok: 'Yes',
37
+ cancel: 'No'
38
+ }).onOk(async () => {
39
+
40
+
41
+ for (let row of selected) {
42
+ await m("deleteFileSystem", {
43
+ name: row.name
44
+ })
45
+ }
46
+ selected.value = []
30
47
 
31
- const { listFileSystem } = await q({ listFileSystem: true });
32
- items.value = listFileSystem
33
48
 
49
+ refresh();
50
+ })
34
51
  }
35
52
 
36
53
  const columns = [
37
- {
38
- name: 'actions',
39
- label: '',
40
- align: 'center'
41
- },
42
54
  {
43
55
  name: 'name',
44
56
  required: true,
@@ -62,13 +74,12 @@ const columns = [
62
74
  align: 'left',
63
75
  }
64
76
  ]
77
+
78
+ const selected = ref([])
65
79
  </script>
66
80
  <template>
67
81
 
68
- <l-page gutter="xs">
69
- <template #header>
70
- <l-btn label="Add" icon="sym_o_add" @click="dialog = true"></l-btn>
71
- </template>
82
+ <l-page title="File system">
72
83
 
73
84
  <q-dialog v-model="dialog" persistent>
74
85
  <q-card style="width: 500px;">
@@ -133,12 +144,15 @@ const columns = [
133
144
  </q-card>
134
145
  </q-dialog>
135
146
 
136
- <l-table :rows="items" :columns="columns">
137
- <template #body-cell-actions="props">
138
- <q-td auto-width>
139
- <q-btn icon="sym_o_delete" @click="onRemove(props.row)" round dense flat class="text-grey"></q-btn>
140
- </q-td>
141
-
147
+ <q-table :rows="items" :columns="columns" selection="multiple" flat bordered dense separator="cell"
148
+ v-model:selected="selected" row-key="name">
149
+ <template #top-left>
150
+ <q-btn icon="sym_o_add" @click="dialog = true" flat round dense>
151
+ <q-tooltip>Add File System</q-tooltip>
152
+ </q-btn>
153
+ <q-btn icon="sym_o_delete" @click="onRemove(selected)" flat round dense :disable="selected.length == 0">
154
+ <q-tooltip>Remove File System</q-tooltip>
155
+ </q-btn>
142
156
  </template>
143
157
 
144
158
  <template #body-cell-data="props">
@@ -147,6 +161,6 @@ const columns = [
147
161
  </q-td>
148
162
  </template>
149
163
 
150
- </l-table>
164
+ </q-table>
151
165
  </l-page>
152
166
  </template>
@@ -32,7 +32,7 @@ const onSubmit = async (data) => {
32
32
  }
33
33
  </script>
34
34
  <template>
35
- <l-page>
35
+ <l-page title="Mail test">
36
36
  <form-kit type="l-form" @submit="onSubmit" :value="{
37
37
  email: my.email,
38
38
  subject: 'Test email',
@@ -1,7 +1,11 @@
1
1
  <script setup>
2
2
  import { ref, computed } from 'vue'
3
3
  import { q } from '#imports'
4
- const { system } = await q({ system: ["package"] })
4
+ const { system } = await q({
5
+ system: {
6
+ package: true
7
+ }
8
+ })
5
9
  const filter = ref("")
6
10
  const filtered = computed(() => {
7
11
  if (!filter.value) return system.package
@@ -14,7 +18,7 @@ const filtered = computed(() => {
14
18
 
15
19
  </script>
16
20
  <template>
17
- <l-page>
21
+ <l-page title="System package">
18
22
  <q-table dense :rows="filtered" :rows-per-page-options="[0]" hide-pagination flat bordered separator="cell">
19
23
  <template v-slot:top-right>
20
24
  <q-input outlined dense debounce="300" v-model="filter" placeholder="Search">
@@ -1,9 +1,13 @@
1
1
  <script setup>
2
- import { q } from '../../'
3
- const { system } = await q({ system: ["phpInfo"] })
2
+ import { q } from '#imports'
3
+ const { system } = await q({
4
+ system: {
5
+ phpInfo: true
6
+ }
7
+ })
4
8
  </script>
5
9
  <template>
6
- <l-page>
10
+ <l-page title="PHP info">
7
11
  <iframe :srcdoc="system.phpInfo" style="height: 700px;" class="full-width no-border"></iframe>
8
12
  </l-page>
9
13
  </template>
@@ -32,7 +32,6 @@ const obj = app.config.reduce((acc, cur) => {
32
32
  return acc
33
33
  }, {});
34
34
 
35
- obj.revision = obj.revision ? obj.revision.split(',') : []
36
35
 
37
36
 
38
37
  const onSubmit = async (d) => {
@@ -76,7 +75,7 @@ const onSubmit = async (d) => {
76
75
  <l-system-setting-general v-if="tab == 'general'" v-model="obj" />
77
76
  <l-system-setting-mail v-if="tab == 'mail'" v-bind="obj" @submit="onSubmit" />
78
77
  <l-system-setting-security v-if="tab == 'security'" v-bind="obj" @submit="onSubmit" />
79
- <l-system-setting-modules v-if="tab == 'Modules'" v-model="obj" />
78
+ <l-system-setting-modules v-if="tab == 'Modules'" v-bind="obj" @submit="onSubmit" />
80
79
  <l-system-setting-developer v-if="tab == 'developer'" v-model="obj" />
81
80
  <l-system-setting-forget-password v-if="tab == 'forget-password'" v-model="obj" />
82
81
  <l-system-setting-authentication v-if="tab == 'authentication'" v-bind="obj" @submit="onSubmit" />