@hostlink/nuxt-light 0.0.90 → 0.0.91
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.
- package/dist/module.json +1 -1
- package/dist/runtime/components/l-app.vue +2 -2
- package/dist/runtime/components/l-date-picker.vue +13 -4
- package/dist/runtime/components/l-field.vue +8 -0
- package/dist/runtime/components/l-table.vue +8 -1
- package/dist/runtime/locales/zh-hk.json +1 -0
- package/dist/runtime/pages/EventLog/index.vue +2 -38
- package/dist/runtime/pages/MailLog/index.vue +33 -32
- package/dist/runtime/pages/User/_user_id/update-role.vue +2 -3
- package/dist/runtime/pages/User/add.vue +2 -2
- package/dist/runtime/pages/User/profile.vue +72 -14
- package/dist/runtime/plugin.mjs +4 -0
- package/dist/runtime/types/EventLog.d.ts +33 -0
- package/dist/runtime/types/EventLog.mjs +32 -0
- package/dist/runtime/types/MailLog.d.ts +30 -0
- package/dist/runtime/types/MailLog.mjs +29 -0
- package/package.json +1 -1
package/dist/module.json
CHANGED
|
@@ -30,13 +30,13 @@ try {
|
|
|
30
30
|
<q-layout v-if="!app.logged">
|
|
31
31
|
<q-page-container class="bg-grey-2" style="color:#1f1f1f">
|
|
32
32
|
<q-page padding>
|
|
33
|
-
<l-login :
|
|
33
|
+
<l-login :two-factor-authentication="app.twoFactorAuthentication"
|
|
34
34
|
:google-client-id="app.googleClientId"></l-login>
|
|
35
35
|
</q-page>
|
|
36
36
|
</q-page-container>
|
|
37
37
|
</q-layout>
|
|
38
38
|
|
|
39
|
-
<l-app-main>
|
|
39
|
+
<l-app-main v-else>
|
|
40
40
|
<slot></slot>
|
|
41
41
|
</l-app-main>
|
|
42
42
|
</template>
|
|
@@ -45,14 +45,21 @@ const localValue = computed({
|
|
|
45
45
|
|
|
46
46
|
const rules = [];
|
|
47
47
|
|
|
48
|
-
if (props.required
|
|
48
|
+
if (props.required) {
|
|
49
49
|
rules.push((val) => {
|
|
50
50
|
if (!val) {
|
|
51
51
|
return "Required";
|
|
52
52
|
}
|
|
53
|
+
})
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (!props.range) {
|
|
57
|
+
rules.push((val) => {
|
|
53
58
|
//check val is YYYY-MM-DD
|
|
54
|
-
if (
|
|
55
|
-
|
|
59
|
+
if (val) {
|
|
60
|
+
if (!val.match(/^\d{4}-\d{2}-\d{2}$/)) {
|
|
61
|
+
return "Invalid date format";
|
|
62
|
+
}
|
|
56
63
|
}
|
|
57
64
|
});
|
|
58
65
|
}
|
|
@@ -70,9 +77,11 @@ const attrs = {
|
|
|
70
77
|
...useAttrs(),
|
|
71
78
|
}
|
|
72
79
|
|
|
80
|
+
const mask = props.range ? "####-##-## - ####-##-##" : "####-##-##";
|
|
81
|
+
|
|
73
82
|
</script>
|
|
74
83
|
<template>
|
|
75
|
-
<q-input v-bind="attrs" v-model="localValue" :rules="rules" :label="$t(label)" hide-bottom-space>
|
|
84
|
+
<q-input v-bind="attrs" v-model="localValue" :rules="rules" :label="$t(label)" hide-bottom-space :mask="mask">
|
|
76
85
|
<template v-slot:prepend>
|
|
77
86
|
<q-btn icon="sym_o_event" round dense flat>
|
|
78
87
|
<q-popup-proxy cover transition-show="scale" transition-hide="scale" ref="popup">
|
|
@@ -338,7 +338,9 @@ const getFilterValue = () => {
|
|
|
338
338
|
if (col.searchable) {
|
|
339
339
|
if (filters.value[col.name]) {
|
|
340
340
|
|
|
341
|
-
if (col.searchType == "
|
|
341
|
+
if (col.searchType == "number") {
|
|
342
|
+
f[col.name] = filters.value[col.name]
|
|
343
|
+
} else if (col.searchType == "date") {
|
|
342
344
|
if (filters.value[col.name].from) {
|
|
343
345
|
f[col.name] = {
|
|
344
346
|
between: [filters.value[col.name].from, filters.value[col.name].to]
|
|
@@ -479,6 +481,11 @@ const filter = ref('');
|
|
|
479
481
|
<q-td v-for="col in props.cols">
|
|
480
482
|
<template v-if="col.searchable">
|
|
481
483
|
|
|
484
|
+
<template v-if="col.searchType == 'number'">
|
|
485
|
+
<q-input dense clearable v-model.number="filters[col.name]" @keydown.enter.prevent="onFilters"
|
|
486
|
+
@clear="onFilters" mask="##########"></q-input>
|
|
487
|
+
</template>
|
|
488
|
+
|
|
482
489
|
<template v-if="col.searchType == 'select'">
|
|
483
490
|
<q-select dense v-model="filters[col.name]" @update:model-value="onFilters" clearable
|
|
484
491
|
:options="col.searchOptions" @clear="onFilters" emit-value />
|
|
@@ -1,42 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
label: "EventLog ID",
|
|
5
|
-
name: "eventlog_id",
|
|
6
|
-
sortable: true,
|
|
7
|
-
searchable: true,
|
|
8
|
-
},
|
|
9
|
-
|
|
10
|
-
{
|
|
11
|
-
label: "Class",
|
|
12
|
-
name: "class",
|
|
13
|
-
sortable: true,
|
|
14
|
-
searchable: true,
|
|
15
|
-
},
|
|
16
|
-
|
|
17
|
-
{
|
|
18
|
-
label: "ID",
|
|
19
|
-
name: "id",
|
|
20
|
-
sortable: true,
|
|
21
|
-
searchable: true,
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
label: "Action",
|
|
25
|
-
name: "action",
|
|
26
|
-
sortable: true,
|
|
27
|
-
searchable: true,
|
|
28
|
-
}, {
|
|
29
|
-
label: "Created time",
|
|
30
|
-
name: "created_time",
|
|
31
|
-
sortable: true,
|
|
32
|
-
searchable: true,
|
|
33
|
-
}, {
|
|
34
|
-
label: "Username",
|
|
35
|
-
name: "username",
|
|
36
|
-
sortable: true,
|
|
37
|
-
searchable: true,
|
|
38
|
-
}
|
|
39
|
-
]
|
|
2
|
+
import { getModelColumns } from "#imports"
|
|
3
|
+
const columns = getModelColumns('EventLog', ['eventlog_id', 'class', 'id', 'action', 'created_time', 'username'])
|
|
40
4
|
|
|
41
5
|
</script>
|
|
42
6
|
|
|
@@ -1,40 +1,41 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
name: "maillog_id",
|
|
6
|
-
sortable: true,
|
|
7
|
-
searchable: true,
|
|
8
|
-
}, {
|
|
9
|
-
label: "From",
|
|
10
|
-
name: "from",
|
|
11
|
-
sortable: true,
|
|
12
|
-
searchable: true,
|
|
13
|
-
}, {
|
|
14
|
-
label: "To",
|
|
15
|
-
name: "to",
|
|
16
|
-
sortable: true,
|
|
17
|
-
searchable: true,
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
label: "Subject",
|
|
21
|
-
name: "subject",
|
|
22
|
-
sortable: true,
|
|
23
|
-
searchable: true,
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
label: "Created time",
|
|
27
|
-
name: "created_time",
|
|
28
|
-
sortable: true,
|
|
29
|
-
searchable: true,
|
|
30
|
-
searchType: "date",
|
|
31
|
-
}
|
|
32
|
-
]
|
|
2
|
+
import { getModelColumns } from "#imports"
|
|
3
|
+
import { ref } from 'vue'
|
|
4
|
+
const columns = getModelColumns("MailLog", ["maillog_id", "from", "to", "subject", "created_time"])
|
|
33
5
|
|
|
6
|
+
|
|
7
|
+
columns.push({
|
|
8
|
+
label: "Content",
|
|
9
|
+
name: "_act",
|
|
10
|
+
gqlField: ["body"]
|
|
11
|
+
})
|
|
12
|
+
const show = ref(false)
|
|
13
|
+
const content = ref("")
|
|
34
14
|
</script>
|
|
35
15
|
|
|
36
16
|
<template>
|
|
37
17
|
<l-page>
|
|
38
|
-
<
|
|
18
|
+
<q-dialog v-model="show" full-width>
|
|
19
|
+
<l-card>
|
|
20
|
+
<q-card-section>
|
|
21
|
+
<iframe width="100%" height="500px" :srcdoc="content" frameborder="0"></iframe>
|
|
22
|
+
</q-card-section>
|
|
23
|
+
</l-card>
|
|
24
|
+
</q-dialog>
|
|
25
|
+
<l-table row-key="maillog_id" @request="$event.loadObjects('MailLog')" :columns="columns" sort-by="maillog_id:desc">
|
|
26
|
+
|
|
27
|
+
<template #body-cell-_act="props">
|
|
28
|
+
<q-td :props="props">
|
|
29
|
+
<l-btn @click="
|
|
30
|
+
content = props.row.body;
|
|
31
|
+
show = true" label="Show" icon="sym_o_visibility">
|
|
32
|
+
</l-btn>
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
</q-td>
|
|
36
|
+
|
|
37
|
+
</template>
|
|
38
|
+
|
|
39
|
+
</l-table>
|
|
39
40
|
</l-page>
|
|
40
41
|
</template>
|
|
@@ -42,11 +42,10 @@ const submit = async () => {
|
|
|
42
42
|
<template>
|
|
43
43
|
<l-page>
|
|
44
44
|
<l-form @submit="submit">
|
|
45
|
-
<
|
|
45
|
+
<l-field label="Roles" stack-label>
|
|
46
46
|
<q-option-group type="checkbox" :options="roles" v-model="obj.roles" inline>
|
|
47
47
|
</q-option-group>
|
|
48
|
-
</
|
|
49
|
-
|
|
48
|
+
</l-field>
|
|
50
49
|
</l-form>
|
|
51
50
|
|
|
52
51
|
</l-page>
|
|
@@ -58,10 +58,10 @@ roles = roles.map((role) => {
|
|
|
58
58
|
|
|
59
59
|
<l-input label="Default page" v-model="obj.default_page"></l-input>
|
|
60
60
|
|
|
61
|
-
<
|
|
61
|
+
<l-field label="Roles" stack-label>
|
|
62
62
|
<q-option-group type="checkbox" :options="roles" v-model="obj.roles" inline>
|
|
63
63
|
</q-option-group>
|
|
64
|
-
</
|
|
64
|
+
</l-field>
|
|
65
65
|
</l-col>
|
|
66
66
|
</l-row>
|
|
67
67
|
</l-form>
|
|
@@ -1,6 +1,50 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { q } from '../../'
|
|
3
|
-
|
|
2
|
+
import { q, getModelColumns } from '../../'
|
|
3
|
+
import { getGQLFields } from '#imports'
|
|
4
|
+
import { toQuery } from '@hostlink/light';
|
|
5
|
+
|
|
6
|
+
const { my } = await q(
|
|
7
|
+
{
|
|
8
|
+
my: ["user_id", "username", "first_name", "last_name", "email", "phone", "roles", "addr1", "addr2", "addr3", "join_date", {
|
|
9
|
+
userLog: {
|
|
10
|
+
__args: {
|
|
11
|
+
sort: "userlog_id:desc"
|
|
12
|
+
},
|
|
13
|
+
data: {
|
|
14
|
+
__args: {
|
|
15
|
+
limit: 10
|
|
16
|
+
},
|
|
17
|
+
...toQuery(getGQLFields('UserLog', ['login_dt', 'result', "user_agent"]))
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
eventLog: {
|
|
21
|
+
__args: {
|
|
22
|
+
sort: "eventlog_id:desc"
|
|
23
|
+
},
|
|
24
|
+
data: {
|
|
25
|
+
__args: {
|
|
26
|
+
limit: 10
|
|
27
|
+
},
|
|
28
|
+
...toQuery(getGQLFields('EventLog', ['class', 'id', 'action', "created_time"]))
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}]
|
|
32
|
+
}
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
const userlogColumns = getModelColumns('UserLog', ['login_dt', 'result', 'user_agent']);
|
|
36
|
+
//remove all searchable
|
|
37
|
+
userlogColumns.forEach(col => {
|
|
38
|
+
col.searchable = false;
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
const eventLogCols = getModelColumns('EventLog', ['class', 'action', 'created_time']);
|
|
43
|
+
//remove all searchable
|
|
44
|
+
eventLogCols.forEach(col => {
|
|
45
|
+
col.searchable = false;
|
|
46
|
+
})
|
|
47
|
+
|
|
4
48
|
</script>
|
|
5
49
|
<template>
|
|
6
50
|
<l-page title="User profile">
|
|
@@ -8,18 +52,32 @@ const my = await q("my", ["user_id", "username", "first_name", "last_name", "ema
|
|
|
8
52
|
<l-btn icon="sym_o_key" to="update-password" label="Update password" />
|
|
9
53
|
<l-btn icon="sym_o_key" to="two-factor-auth" label="Two factor auth" />
|
|
10
54
|
</template>
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
<l-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
55
|
+
|
|
56
|
+
<div class="q-gutter-md q-mt-md">
|
|
57
|
+
<l-card>
|
|
58
|
+
<l-list>
|
|
59
|
+
<l-item label="Username">{{ my.username }}</l-item>
|
|
60
|
+
<l-item label="First name">{{ my.first_name }}</l-item>
|
|
61
|
+
<l-item label="Last name">{{ my.last_name }}</l-item>
|
|
62
|
+
<l-item label="Email">{{ my.email }}</l-item>
|
|
63
|
+
<l-item label="Phone">{{ my.phone }}</l-item>
|
|
64
|
+
<l-item label="Address">{{ my.addr1 }} {{ my.addr2 }} {{ my.addr3 }}</l-item>
|
|
65
|
+
<l-item label="Join date">{{ my.join_date }}</l-item>
|
|
66
|
+
<l-item label="Roles">{{ my.roles.join(",") }}</l-item>
|
|
67
|
+
</l-list>
|
|
68
|
+
</l-card>
|
|
69
|
+
|
|
70
|
+
<l-card title="User Log">
|
|
71
|
+
<l-table :rows="my.userLog.data" :columns="userlogColumns" searchable :rows-per-page-options="[0]">
|
|
72
|
+
</l-table>
|
|
73
|
+
</l-card>
|
|
74
|
+
|
|
75
|
+
<l-card title="Event Log">
|
|
76
|
+
<l-table :rows="my.eventLog.data" :columns="eventLogCols" searchable :rows-per-page-options="[0]">
|
|
77
|
+
</l-table>
|
|
78
|
+
</l-card>
|
|
79
|
+
</div>
|
|
80
|
+
|
|
23
81
|
|
|
24
82
|
</l-page>
|
|
25
83
|
</template>
|
package/dist/runtime/plugin.mjs
CHANGED
|
@@ -12,10 +12,14 @@ import { useLight } from "./index.mjs";
|
|
|
12
12
|
import TypeUser from "./types/User.mjs";
|
|
13
13
|
import TypeUserLog from "./types/UserLog.mjs";
|
|
14
14
|
import TypeSystemValue from "./types/SystemValue.mjs";
|
|
15
|
+
import TypeMailLog from "./types/MailLog.mjs";
|
|
16
|
+
import TypeEventLog from "./types/EventLog.mjs";
|
|
15
17
|
export default defineNuxtPlugin((nuxtApp) => {
|
|
16
18
|
defineModel("User", TypeUser);
|
|
17
19
|
defineModel("UserLog", TypeUserLog);
|
|
18
20
|
defineModel("SystemValue", TypeSystemValue);
|
|
21
|
+
defineModel("MailLog", TypeMailLog);
|
|
22
|
+
defineModel("EventLog", TypeEventLog);
|
|
19
23
|
nuxtApp.vueApp.config.errorHandler = (error) => {
|
|
20
24
|
console.log(error);
|
|
21
25
|
const light = useLight();
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
eventlog_id: {
|
|
3
|
+
label: string;
|
|
4
|
+
sortable: boolean;
|
|
5
|
+
searchable: boolean;
|
|
6
|
+
};
|
|
7
|
+
class: {
|
|
8
|
+
label: string;
|
|
9
|
+
sortable: boolean;
|
|
10
|
+
searchable: boolean;
|
|
11
|
+
};
|
|
12
|
+
id: {
|
|
13
|
+
label: string;
|
|
14
|
+
sortable: boolean;
|
|
15
|
+
searchable: boolean;
|
|
16
|
+
};
|
|
17
|
+
action: {
|
|
18
|
+
label: string;
|
|
19
|
+
sortable: boolean;
|
|
20
|
+
searchable: boolean;
|
|
21
|
+
};
|
|
22
|
+
created_time: {
|
|
23
|
+
label: string;
|
|
24
|
+
sortable: boolean;
|
|
25
|
+
searchable: boolean;
|
|
26
|
+
};
|
|
27
|
+
username: {
|
|
28
|
+
label: string;
|
|
29
|
+
sortable: boolean;
|
|
30
|
+
searchable: boolean;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
export default _default;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
eventlog_id: {
|
|
3
|
+
label: "EventLog ID",
|
|
4
|
+
sortable: true,
|
|
5
|
+
searchable: true
|
|
6
|
+
},
|
|
7
|
+
class: {
|
|
8
|
+
label: "Class",
|
|
9
|
+
sortable: true,
|
|
10
|
+
searchable: true
|
|
11
|
+
},
|
|
12
|
+
id: {
|
|
13
|
+
label: "ID",
|
|
14
|
+
sortable: true,
|
|
15
|
+
searchable: true
|
|
16
|
+
},
|
|
17
|
+
action: {
|
|
18
|
+
label: "Action",
|
|
19
|
+
sortable: true,
|
|
20
|
+
searchable: true
|
|
21
|
+
},
|
|
22
|
+
created_time: {
|
|
23
|
+
label: "Created time",
|
|
24
|
+
sortable: true,
|
|
25
|
+
searchable: true
|
|
26
|
+
},
|
|
27
|
+
username: {
|
|
28
|
+
label: "Username",
|
|
29
|
+
sortable: true,
|
|
30
|
+
searchable: true
|
|
31
|
+
}
|
|
32
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
maillog_id: {
|
|
3
|
+
label: string;
|
|
4
|
+
sortable: boolean;
|
|
5
|
+
searchable: boolean;
|
|
6
|
+
searchType: string;
|
|
7
|
+
};
|
|
8
|
+
from: {
|
|
9
|
+
label: string;
|
|
10
|
+
sortable: boolean;
|
|
11
|
+
searchable: boolean;
|
|
12
|
+
};
|
|
13
|
+
to: {
|
|
14
|
+
label: string;
|
|
15
|
+
sortable: boolean;
|
|
16
|
+
searchable: boolean;
|
|
17
|
+
};
|
|
18
|
+
subject: {
|
|
19
|
+
label: string;
|
|
20
|
+
sortable: boolean;
|
|
21
|
+
searchable: boolean;
|
|
22
|
+
};
|
|
23
|
+
created_time: {
|
|
24
|
+
label: string;
|
|
25
|
+
sortable: boolean;
|
|
26
|
+
searchable: boolean;
|
|
27
|
+
searchType: string;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
export default _default;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
maillog_id: {
|
|
3
|
+
label: "ID",
|
|
4
|
+
sortable: true,
|
|
5
|
+
searchable: true,
|
|
6
|
+
searchType: "number"
|
|
7
|
+
},
|
|
8
|
+
from: {
|
|
9
|
+
label: "From",
|
|
10
|
+
sortable: true,
|
|
11
|
+
searchable: true
|
|
12
|
+
},
|
|
13
|
+
to: {
|
|
14
|
+
label: "To",
|
|
15
|
+
sortable: true,
|
|
16
|
+
searchable: true
|
|
17
|
+
},
|
|
18
|
+
subject: {
|
|
19
|
+
label: "Subject",
|
|
20
|
+
sortable: true,
|
|
21
|
+
searchable: true
|
|
22
|
+
},
|
|
23
|
+
created_time: {
|
|
24
|
+
label: "Created time",
|
|
25
|
+
sortable: true,
|
|
26
|
+
searchable: true,
|
|
27
|
+
searchType: "date"
|
|
28
|
+
}
|
|
29
|
+
};
|