@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 CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "light",
3
3
  "configKey": "light",
4
- "version": "0.0.90"
4
+ "version": "0.0.91"
5
5
  }
@@ -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 :twoFactojrAuthentication="app.twoFactorAuthentication"
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 && !props.range) {
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 (!val.match(/^\d{4}-\d{2}-\d{2}$/)) {
55
- return "Invalid date format";
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">
@@ -0,0 +1,8 @@
1
+ <script setup>
2
+ const props = defineProps(['label']);
3
+ </script>
4
+ <template>
5
+ <q-field :label="$t(props.label ?? '')">
6
+ <slot></slot>
7
+ </q-field>
8
+ </template>
@@ -338,7 +338,9 @@ const getFilterValue = () => {
338
338
  if (col.searchable) {
339
339
  if (filters.value[col.name]) {
340
340
 
341
- if (col.searchType == "date") {
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 />
@@ -157,4 +157,5 @@
157
157
  "Event Log": "事件紀錄",
158
158
  "Mail Log": "郵件紀錄",
159
159
  "User Log": "使用者紀錄"
160
+
160
161
  }
@@ -1,42 +1,6 @@
1
1
  <script setup>
2
- const columns = [
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
- const columns = [
3
- {
4
- label: "ID",
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
- <l-table @request="$event.loadObjects('MailLog')" :columns="columns" sort-by="maillog_id:desc" />
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
- <q-field label="Roles" stack-label>
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
- </q-field>
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
- <q-field label="Roles" stack-label>
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
- </q-field>
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
- const my = await q("my", ["user_id", "username", "first_name", "last_name", "email", "phone", "roles", "addr1", "addr2", "addr3", "join_date"])
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
- <l-card>
12
- <l-list>
13
- <l-item label="Username">{{ my.username }}</l-item>
14
- <l-item label="First name">{{ my.first_name }}</l-item>
15
- <l-item label="Last name">{{ my.last_name }}</l-item>
16
- <l-item label="Email">{{ my.email }}</l-item>
17
- <l-item label="Phone">{{ my.phone }}</l-item>
18
- <l-item label="Address">{{ my.addr1 }} {{ my.addr2 }} {{ my.addr3 }}</l-item>
19
- <l-item label="Join date">{{ my.join_date }}</l-item>
20
- <l-item label="Roles">{{ my.roles.join(",") }}</l-item>
21
- </l-list>
22
- </l-card>
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>
@@ -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
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hostlink/nuxt-light",
3
- "version": "0.0.90",
3
+ "version": "0.0.91",
4
4
  "description": "HostLink Nuxt Light Framework",
5
5
  "repository": "@hostlink/nuxt-light",
6
6
  "license": "MIT",