@hostlink/nuxt-light 1.21.2 → 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.
@@ -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" />
@@ -2,34 +2,43 @@
2
2
  import { q, getGQLFields, model } from '#imports'
3
3
  import { toQuery } from '@hostlink/light';
4
4
 
5
- const { my } = await q(
6
- {
7
- my: ["user_id", "username", "first_name", "last_name", "email", "phone", "roles", "addr1", "addr2", "addr3", "join_date", {
8
- userLog: {
5
+ const { my } = await q({
6
+ my: {
7
+ user_id: true,
8
+ username: true,
9
+ first_name: true,
10
+ last_name: true,
11
+ email: true,
12
+ phone: true,
13
+ roles: true,
14
+ addr1: true,
15
+ addr2: true,
16
+ addr3: true,
17
+ join_date: true,
18
+ userLog: {
19
+ __args: {
20
+ sort: "userlog_id:desc"
21
+ },
22
+ data: {
9
23
  __args: {
10
- sort: "userlog_id:desc"
24
+ limit: 10
11
25
  },
12
- data: {
13
- __args: {
14
- limit: 10
15
- },
16
- ...toQuery(getGQLFields('UserLog', ['login_dt', 'result', "user_agent"]))
17
- }
26
+ ...toQuery(getGQLFields('UserLog', ['login_dt', 'result', "user_agent"]))
27
+ }
28
+ },
29
+ eventLog: {
30
+ __args: {
31
+ sort: "eventlog_id:desc"
18
32
  },
19
- eventLog: {
33
+ data: {
20
34
  __args: {
21
- sort: "eventlog_id:desc"
35
+ limit: 10
22
36
  },
23
- data: {
24
- __args: {
25
- limit: 10
26
- },
27
- ...toQuery(getGQLFields('EventLog', ['class', 'id', 'action', "created_time"]))
28
- }
37
+ ...toQuery(getGQLFields('EventLog', ['class', 'id', 'action', "created_time"]))
29
38
  }
30
- }]
39
+ }
31
40
  }
32
- )
41
+ })
33
42
 
34
43
  const userlogColumns = model('UserLog').columns(['login_dt', 'result', 'user_agent']);
35
44
  //remove all searchable
@@ -47,7 +56,6 @@ eventLogCols.forEach(col => {
47
56
  </script>
48
57
  <template>
49
58
  <l-page title="User profile" gutter="sm">
50
-
51
59
  <template #header>
52
60
  <l-btn icon="sym_o_password" to="setting/password" label="Update password" />
53
61
  <l-btn icon="sym_o_key" to="setting/two-factor-auth" label="Two factor auth" />
@@ -55,9 +63,7 @@ eventLogCols.forEach(col => {
55
63
 
56
64
  <l-row>
57
65
  <l-col md="4">
58
-
59
66
  <l-card>
60
-
61
67
  <q-card-section class="text-h5 text-center">
62
68
  {{ my.first_name }} {{ my.last_name }}
63
69
  </q-card-section>
@@ -1,25 +1,16 @@
1
1
  <script setup>
2
- import { reactive } from "vue"
3
2
  import { reset } from "@formkit/core"
4
- import { q, m, notify } from '../../../'
3
+ import { q, m, notify } from '#imports'
5
4
 
6
- const obj = reactive(await q("my", ["username", "email", "first_name", "last_name"]))
7
- const save = async () => {
8
- try {
9
- await m("updateMy", {
10
- data: {
11
- email: obj.email,
12
- first_name: obj.first_name,
13
- last_name: obj.last_name
14
-
15
- }
16
- });
17
- notify("Your profile has been updated")
18
-
19
- } catch (e) {
20
- notify(e.message, "red")
5
+ const { my } = await q({
6
+ my: {
7
+ username: true,
8
+ email: true,
9
+ first_name: true,
10
+ last_name: true
21
11
  }
22
- }
12
+ })
13
+
23
14
  const onSubmit = async (data, form) => {
24
15
  return await m("updateMy", {
25
16
  data: {
@@ -34,7 +25,7 @@ const onSubmit = async (data, form) => {
34
25
  }
35
26
  </script>
36
27
  <template>
37
- <FormKit type="l-form" :value="obj" :bordered="false" @submit="onSubmit">
28
+ <FormKit type="l-form" :value="my" :bordered="false" @submit="onSubmit">
38
29
  <FormKit type="l-input" label="Username" name="username" readonly></FormKit>
39
30
  <FormKit type="l-input" label="Email" name="email" validation="required|email"></FormKit>
40
31
  <FormKit type="l-input" label="First name" name="first_name" validation="required"></FormKit>
@@ -1,7 +1,14 @@
1
1
  <script setup>
2
2
  import { reset } from "@formkit/core"
3
- import { q, m, notify } from '../../../'
4
- const obj = await q("my", ["phone", "addr1", "addr2", "addr3"])
3
+ import { q, m, notify } from '#imports'
4
+ const { my } = await q({
5
+ my: {
6
+ phone: true,
7
+ addr1: true,
8
+ addr2: true,
9
+ addr3: true
10
+ }
11
+ })
5
12
  const onSubmit = (data, form) => {
6
13
  return m("updateMy", {
7
14
  data: {
@@ -17,7 +24,7 @@ const onSubmit = (data, form) => {
17
24
  }
18
25
  </script>
19
26
  <template>
20
- <FormKit type="l-form" :value="obj" :bordered="false" @submit="onSubmit">
27
+ <FormKit type="l-form" :value="my" :bordered="false" @submit="onSubmit">
21
28
  <FormKit type="l-input" label="Phone" name="phone"></FormKit>
22
29
  <FormKit type="l-input" label="Address1" name="addr1"></FormKit>
23
30
  <FormKit type="l-input" label="Address2" name="addr2"></FormKit>
@@ -1,7 +1,11 @@
1
1
  <script setup>
2
2
  import { q, m } from '#imports'
3
3
  import { reactive } from 'vue'
4
- let my = await q("my", ["styles"]);
4
+ let { my } = await q({
5
+ my: {
6
+ styles: true
7
+ }
8
+ });
5
9
 
6
10
  const styles = reactive({
7
11
 
@@ -155,8 +159,7 @@ const columns = [
155
159
  { label: 'A', value: 'a' },
156
160
  { label: 'B', value: 'b' },
157
161
  { label: 'C', value: 'c' }
158
- ]"
159
- />
162
+ ]" />
160
163
 
161
164
  <q-table :columns="columns" :rows="[
162
165
  { name: 'A', phone: '123' },