@hostlink/nuxt-light 1.67.8 → 1.68.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.
- package/dist/module.json +1 -1
- package/dist/module.mjs +103 -286
- package/dist/runtime/components/L/AppMain.d.vue.ts +4 -4
- package/dist/runtime/components/L/AppMain.vue +2 -0
- package/dist/runtime/components/L/AppMain.vue.d.ts +4 -4
- package/dist/runtime/components/L/NotificationBell.vue +187 -0
- package/dist/runtime/components/L/Table.d.vue.ts +12 -6
- package/dist/runtime/components/L/Table.vue +7 -1
- package/dist/runtime/components/L/Table.vue.d.ts +12 -6
- package/dist/runtime/models/Notification.d.ts +2 -0
- package/dist/runtime/models/Notification.js +52 -0
- package/dist/runtime/models/SystemValue.js +3 -1
- package/dist/runtime/pages/Notification/index.vue +55 -0
- package/dist/runtime/pages/User/[user_id]/update-role.d.vue.ts +3 -0
- package/dist/runtime/pages/User/[user_id]/update-role.vue.d.ts +3 -0
- package/dist/runtime/pages/User/[user_id]/view.d.vue.ts +3 -0
- package/dist/runtime/pages/User/[user_id]/view.vue.d.ts +3 -0
- package/package.json +1 -1
- /package/dist/runtime/{pages/EventLog/_eventlog_id/view.d.vue.ts → components/L/NotificationBell.d.vue.ts} +0 -0
- /package/dist/runtime/{pages/EventLog/_eventlog_id/view.vue.d.ts → components/L/NotificationBell.vue.d.ts} +0 -0
- /package/dist/runtime/pages/{User/_user_id → EventLog/[eventlog_id]}/view.d.vue.ts +0 -0
- /package/dist/runtime/pages/EventLog/{_eventlog_id → [eventlog_id]}/view.vue +0 -0
- /package/dist/runtime/pages/{User/_user_id → EventLog/[eventlog_id]}/view.vue.d.ts +0 -0
- /package/dist/runtime/pages/{Role/_name/update-child.d.vue.ts → Notification/index.d.vue.ts} +0 -0
- /package/dist/runtime/pages/{Role/_name/update-child.vue.d.ts → Notification/index.vue.d.ts} +0 -0
- /package/dist/runtime/pages/{SystemValue/_systemvalue_id/edit.d.vue.ts → Role/[name]/update-child.d.vue.ts} +0 -0
- /package/dist/runtime/pages/Role/{_name → [name]}/update-child.vue +0 -0
- /package/dist/runtime/pages/{SystemValue/_systemvalue_id/edit.vue.d.ts → Role/[name]/update-child.vue.d.ts} +0 -0
- /package/dist/runtime/pages/{User/_user_id → SystemValue/[systemvalue_id]}/edit.d.vue.ts +0 -0
- /package/dist/runtime/pages/SystemValue/{_systemvalue_id → [systemvalue_id]}/edit.vue +0 -0
- /package/dist/runtime/pages/{User/_user_id → SystemValue/[systemvalue_id]}/edit.vue.d.ts +0 -0
- /package/dist/runtime/pages/User/{_user_id → [user_id]}/change-password.d.vue.ts +0 -0
- /package/dist/runtime/pages/User/{_user_id → [user_id]}/change-password.vue +0 -0
- /package/dist/runtime/pages/User/{_user_id → [user_id]}/change-password.vue.d.ts +0 -0
- /package/dist/runtime/pages/User/{_user_id/update-role.d.vue.ts → [user_id]/edit.d.vue.ts} +0 -0
- /package/dist/runtime/pages/User/{_user_id → [user_id]}/edit.vue +0 -0
- /package/dist/runtime/pages/User/{_user_id/update-role.vue.d.ts → [user_id]/edit.vue.d.ts} +0 -0
- /package/dist/runtime/pages/User/{_user_id → [user_id]}/update-role.vue +0 -0
- /package/dist/runtime/pages/User/{_user_id → [user_id]}/view.vue +0 -0
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,283 +1,100 @@
|
|
|
1
1
|
import { defineNuxtModule, createResolver, extendPages, addImports, addComponentsDir, addImportsDir, resolveFiles, addPluginTemplate, addPlugin } from '@nuxt/kit';
|
|
2
|
+
import { readdirSync } from 'node:fs';
|
|
3
|
+
import { basename, join, relative, dirname } from 'node:path';
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
{
|
|
30
|
-
name
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
file: "runtime/pages/Translate/index.vue"
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
name: "User",
|
|
56
|
-
path: "/User",
|
|
57
|
-
file: "runtime/pages/User/index.vue"
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
name: "UserLog",
|
|
61
|
-
path: "/UserLog",
|
|
62
|
-
file: "runtime/pages/UserLog/index.vue"
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
name: "Permission-add",
|
|
66
|
-
path: "/Permission/add",
|
|
67
|
-
file: "runtime/pages/Permission/add.vue"
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
name: "Permission-all",
|
|
71
|
-
path: "/Permission/all",
|
|
72
|
-
file: "runtime/pages/Permission/all.vue"
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
name: "Permission-export",
|
|
76
|
-
path: "/Permission/export",
|
|
77
|
-
file: "runtime/pages/Permission/export.vue"
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
name: "Role-add",
|
|
81
|
-
path: "/Role/add",
|
|
82
|
-
file: "runtime/pages/Role/add.vue"
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
name: "Role-add2",
|
|
86
|
-
path: "/Role/add2",
|
|
87
|
-
file: "runtime/pages/Role/add2.vue"
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
name: "System-fs",
|
|
91
|
-
path: "/System/fs",
|
|
92
|
-
file: "runtime/pages/System/fs.vue"
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
name: "System-mailtest",
|
|
96
|
-
path: "/System/mailtest",
|
|
97
|
-
file: "runtime/pages/System/mailtest.vue"
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
name: "System-package",
|
|
101
|
-
path: "/System/package",
|
|
102
|
-
file: "runtime/pages/System/package.vue"
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
name: "System-phpinfo",
|
|
106
|
-
path: "/System/phpinfo",
|
|
107
|
-
file: "runtime/pages/System/phpinfo.vue"
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
name: "System-setting",
|
|
111
|
-
path: "/System/setting",
|
|
112
|
-
file: "runtime/pages/System/setting.vue"
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
name: "System-test",
|
|
116
|
-
path: "/System/test",
|
|
117
|
-
file: "runtime/pages/System/test.vue"
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
name: "System-view_as",
|
|
121
|
-
path: "/System/view_as",
|
|
122
|
-
file: "runtime/pages/System/view_as.vue"
|
|
123
|
-
},
|
|
124
|
-
{
|
|
125
|
-
name: "System-menu",
|
|
126
|
-
path: "/System/menu",
|
|
127
|
-
file: "runtime/pages/System/menu/index.vue"
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
name: "SystemValue-add",
|
|
131
|
-
path: "/SystemValue/add",
|
|
132
|
-
file: "runtime/pages/SystemValue/add.vue"
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
name: "System-database-check",
|
|
136
|
-
path: "/System/database/check",
|
|
137
|
-
file: "runtime/pages/System/database/check.vue"
|
|
138
|
-
},
|
|
139
|
-
{
|
|
140
|
-
name: "System-database-migrate",
|
|
141
|
-
path: "/System/database/migrate",
|
|
142
|
-
file: "runtime/pages/System/database/migrate.vue"
|
|
143
|
-
},
|
|
144
|
-
{
|
|
145
|
-
name: "System-database-process",
|
|
146
|
-
path: "/System/database/process",
|
|
147
|
-
file: "runtime/pages/System/database/process.vue"
|
|
148
|
-
},
|
|
149
|
-
{
|
|
150
|
-
name: "System-database-restore",
|
|
151
|
-
path: "/System/database/restore",
|
|
152
|
-
file: "runtime/pages/System/database/restore.vue"
|
|
153
|
-
},
|
|
154
|
-
{
|
|
155
|
-
name: "System-database-backup",
|
|
156
|
-
path: "/System/database/backup",
|
|
157
|
-
file: "runtime/pages/System/database/backup.vue"
|
|
158
|
-
},
|
|
159
|
-
{
|
|
160
|
-
name: "System-database-table",
|
|
161
|
-
path: "/System/database/table",
|
|
162
|
-
file: "runtime/pages/System/database/table.vue"
|
|
163
|
-
},
|
|
164
|
-
{
|
|
165
|
-
name: "System-database-event",
|
|
166
|
-
path: "/System/database/event",
|
|
167
|
-
file: "runtime/pages/System/database/event.vue"
|
|
168
|
-
},
|
|
169
|
-
{
|
|
170
|
-
name: "EventLog-eventlog_id-view",
|
|
171
|
-
path: "/EventLog/:eventlog_id/view",
|
|
172
|
-
file: "runtime/pages/EventLog/_eventlog_id/view.vue"
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
name: "Role-name-update-child",
|
|
176
|
-
path: "/Role/:name/update-child",
|
|
177
|
-
file: "runtime/pages/Role/_name/update-child.vue"
|
|
178
|
-
},
|
|
179
|
-
{
|
|
180
|
-
name: "SystemValue-systemvalue_id-edit",
|
|
181
|
-
path: "/SystemValue/:systemvalue_id/edit",
|
|
182
|
-
file: "runtime/pages/SystemValue/_systemvalue_id/edit.vue"
|
|
183
|
-
},
|
|
184
|
-
{
|
|
185
|
-
name: "User-user_id-change-password",
|
|
186
|
-
path: "/User/:user_id/change-password",
|
|
187
|
-
file: "runtime/pages/User/_user_id/change-password.vue"
|
|
188
|
-
},
|
|
189
|
-
{
|
|
190
|
-
name: "User-user_id-edit",
|
|
191
|
-
path: "/User/:user_id/edit",
|
|
192
|
-
file: "runtime/pages/User/_user_id/edit.vue"
|
|
193
|
-
},
|
|
194
|
-
{
|
|
195
|
-
name: "User-user_id-update-role",
|
|
196
|
-
path: "/User/:user_id/update-role",
|
|
197
|
-
file: "runtime/pages/User/_user_id/update-role.vue"
|
|
198
|
-
},
|
|
199
|
-
{
|
|
200
|
-
name: "User",
|
|
201
|
-
path: "/User",
|
|
202
|
-
file: "runtime/pages/User/index.vue"
|
|
203
|
-
},
|
|
204
|
-
{
|
|
205
|
-
name: "User-add",
|
|
206
|
-
path: "/User/add",
|
|
207
|
-
file: "runtime/pages/User/add.vue"
|
|
208
|
-
},
|
|
209
|
-
{
|
|
210
|
-
name: "User-user_id-view",
|
|
211
|
-
path: "/User/:user_id/view",
|
|
212
|
-
file: "runtime/pages/User/_user_id/view.vue"
|
|
213
|
-
},
|
|
214
|
-
{
|
|
215
|
-
name: "User-profile",
|
|
216
|
-
path: "/User/profile",
|
|
217
|
-
file: "runtime/pages/User/profile.vue"
|
|
218
|
-
},
|
|
219
|
-
{
|
|
220
|
-
name: "User-createAccessToken",
|
|
221
|
-
path: "/User/createAccessToken",
|
|
222
|
-
file: "runtime/pages/User/createAccessToken.vue"
|
|
223
|
-
},
|
|
224
|
-
{
|
|
225
|
-
path: "/User/setting",
|
|
226
|
-
file: "runtime/pages/User/setting.vue",
|
|
227
|
-
children: [
|
|
228
|
-
{
|
|
229
|
-
name: "User-setting",
|
|
230
|
-
path: "",
|
|
231
|
-
file: "runtime/pages/User/setting/index.vue"
|
|
232
|
-
},
|
|
233
|
-
{
|
|
234
|
-
name: "User-setting-bio-auth",
|
|
235
|
-
path: "bio-auth",
|
|
236
|
-
file: "runtime/pages/User/setting/bio-auth.vue"
|
|
237
|
-
},
|
|
238
|
-
{
|
|
239
|
-
name: "User-setting-information",
|
|
240
|
-
path: "information",
|
|
241
|
-
file: "runtime/pages/User/setting/information.vue"
|
|
242
|
-
},
|
|
243
|
-
{
|
|
244
|
-
name: "User-setting-favorite",
|
|
245
|
-
path: "favorite",
|
|
246
|
-
file: "runtime/pages/User/setting/favorite.vue"
|
|
247
|
-
},
|
|
248
|
-
{
|
|
249
|
-
name: "User-setting-menu",
|
|
250
|
-
path: "menu",
|
|
251
|
-
file: "runtime/pages/User/setting/menu.vue"
|
|
252
|
-
},
|
|
253
|
-
{
|
|
254
|
-
name: "User-setting-open_id",
|
|
255
|
-
path: "open_id",
|
|
256
|
-
file: "runtime/pages/User/setting/open_id.vue"
|
|
257
|
-
},
|
|
258
|
-
{
|
|
259
|
-
name: "User-setting-password",
|
|
260
|
-
path: "password",
|
|
261
|
-
file: "runtime/pages/User/setting/password.vue"
|
|
262
|
-
},
|
|
263
|
-
{
|
|
264
|
-
name: "User-setting-style",
|
|
265
|
-
path: "style",
|
|
266
|
-
file: "runtime/pages/User/setting/style.vue"
|
|
267
|
-
},
|
|
268
|
-
{
|
|
269
|
-
name: "User-setting-two-factor-auth",
|
|
270
|
-
path: "two-factor-auth",
|
|
271
|
-
file: "runtime/pages/User/setting/two-factor-auth.vue"
|
|
272
|
-
},
|
|
273
|
-
{
|
|
274
|
-
name: "User-setting-sessions",
|
|
275
|
-
path: "sessions",
|
|
276
|
-
file: "runtime/pages/User/setting/sessions.vue"
|
|
5
|
+
function buildPath(dirParts, fileName) {
|
|
6
|
+
const parts = [...dirParts];
|
|
7
|
+
if (fileName !== "index") {
|
|
8
|
+
parts.push(fileName);
|
|
9
|
+
}
|
|
10
|
+
return "/" + parts.map((p) => {
|
|
11
|
+
if (p.startsWith("[") && p.endsWith("]")) {
|
|
12
|
+
return ":" + p.slice(1, -1);
|
|
13
|
+
}
|
|
14
|
+
return p;
|
|
15
|
+
}).join("/");
|
|
16
|
+
}
|
|
17
|
+
function buildName(dirParts, fileName) {
|
|
18
|
+
const parts = [...dirParts];
|
|
19
|
+
if (fileName !== "index") {
|
|
20
|
+
parts.push(fileName);
|
|
21
|
+
}
|
|
22
|
+
return parts.map((p) => {
|
|
23
|
+
if (p.startsWith("[") && p.endsWith("]")) {
|
|
24
|
+
return p.slice(1, -1);
|
|
25
|
+
}
|
|
26
|
+
return p;
|
|
27
|
+
}).join("-");
|
|
28
|
+
}
|
|
29
|
+
function scanRoutes(pagesDir, dir) {
|
|
30
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
31
|
+
const files = entries.filter((e) => e.isFile() && e.name.endsWith(".vue")).sort((a, b) => {
|
|
32
|
+
if (a.name === "index.vue") return -1;
|
|
33
|
+
if (b.name === "index.vue") return 1;
|
|
34
|
+
return a.name.localeCompare(b.name);
|
|
35
|
+
});
|
|
36
|
+
const dirs = entries.filter((e) => e.isDirectory());
|
|
37
|
+
const result = [];
|
|
38
|
+
const handledDirs = /* @__PURE__ */ new Set();
|
|
39
|
+
for (const file of files) {
|
|
40
|
+
const baseName = basename(file.name, ".vue");
|
|
41
|
+
const siblingDir = dirs.find((d) => d.name === baseName);
|
|
42
|
+
if (siblingDir) {
|
|
43
|
+
handledDirs.add(baseName);
|
|
44
|
+
const filePath = join(dir, file.name);
|
|
45
|
+
const relPath = relative(pagesDir, filePath);
|
|
46
|
+
const dirParts = dirname(relPath).split("/").filter((p) => p && p !== ".");
|
|
47
|
+
const parentPath = buildPath(dirParts, baseName);
|
|
48
|
+
const children = scanRoutes(pagesDir, join(dir, baseName));
|
|
49
|
+
for (const child of children) {
|
|
50
|
+
child.path = child.path.replace(parentPath, "");
|
|
51
|
+
if (child.path.startsWith("/")) {
|
|
52
|
+
child.path = child.path.slice(1);
|
|
53
|
+
}
|
|
277
54
|
}
|
|
278
|
-
|
|
55
|
+
result.push({
|
|
56
|
+
path: parentPath,
|
|
57
|
+
file: relPath,
|
|
58
|
+
children
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
for (const file of files) {
|
|
63
|
+
const baseName = basename(file.name, ".vue");
|
|
64
|
+
const siblingDir = dirs.find((d) => d.name === baseName);
|
|
65
|
+
if (!siblingDir) {
|
|
66
|
+
const filePath = join(dir, file.name);
|
|
67
|
+
const relPath = relative(pagesDir, filePath);
|
|
68
|
+
const dirParts = dirname(relPath).split("/").filter((p) => p && p !== ".");
|
|
69
|
+
result.push({
|
|
70
|
+
name: buildName(dirParts, baseName),
|
|
71
|
+
path: buildPath(dirParts, baseName),
|
|
72
|
+
file: relPath
|
|
73
|
+
});
|
|
74
|
+
}
|
|
279
75
|
}
|
|
280
|
-
|
|
76
|
+
for (const d of dirs) {
|
|
77
|
+
if (!handledDirs.has(d.name)) {
|
|
78
|
+
result.push(...scanRoutes(pagesDir, join(dir, d.name)));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
function generateRoutes(pagesDir) {
|
|
84
|
+
return scanRoutes(pagesDir, pagesDir);
|
|
85
|
+
}
|
|
86
|
+
function resolveRouteFiles(routes, resolve) {
|
|
87
|
+
return routes.map((route) => {
|
|
88
|
+
const resolved = {
|
|
89
|
+
...route,
|
|
90
|
+
file: resolve(`runtime/pages/${route.file}`)
|
|
91
|
+
};
|
|
92
|
+
if (route.children) {
|
|
93
|
+
resolved.children = resolveRouteFiles(route.children, resolve);
|
|
94
|
+
}
|
|
95
|
+
return resolved;
|
|
96
|
+
});
|
|
97
|
+
}
|
|
281
98
|
|
|
282
99
|
const module$1 = defineNuxtModule({
|
|
283
100
|
meta: {
|
|
@@ -349,26 +166,26 @@ const module$1 = defineNuxtModule({
|
|
|
349
166
|
}
|
|
350
167
|
};
|
|
351
168
|
nuxt.options.runtimeConfig = runtimeConfig;
|
|
169
|
+
const pagesDir = resolver.resolve("./runtime/pages");
|
|
170
|
+
const generatedRoutes = resolveRouteFiles(generateRoutes(pagesDir), resolver.resolve);
|
|
352
171
|
extendPages((pages) => {
|
|
353
|
-
for (const route of
|
|
172
|
+
for (const route of generatedRoutes) {
|
|
354
173
|
if (route.children) {
|
|
355
174
|
pages.unshift({
|
|
356
175
|
path: route.path,
|
|
357
|
-
file:
|
|
358
|
-
children: route.children.map((child) => {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
};
|
|
364
|
-
})
|
|
176
|
+
file: route.file,
|
|
177
|
+
children: route.children.map((child) => ({
|
|
178
|
+
name: child.name,
|
|
179
|
+
path: child.path,
|
|
180
|
+
file: child.file
|
|
181
|
+
}))
|
|
365
182
|
});
|
|
366
183
|
continue;
|
|
367
184
|
}
|
|
368
185
|
pages.unshift({
|
|
369
186
|
name: route.name,
|
|
370
187
|
path: route.path,
|
|
371
|
-
file:
|
|
188
|
+
file: route.file
|
|
372
189
|
});
|
|
373
190
|
}
|
|
374
191
|
});
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
declare var __VLS_38: {},
|
|
1
|
+
declare var __VLS_38: {}, __VLS_245: {}, __VLS_356: {}, __VLS_363: {};
|
|
2
2
|
type __VLS_Slots = {} & {
|
|
3
3
|
header?: (props: typeof __VLS_38) => any;
|
|
4
4
|
} & {
|
|
5
|
-
'user-menu'?: (props: typeof
|
|
5
|
+
'user-menu'?: (props: typeof __VLS_245) => any;
|
|
6
6
|
} & {
|
|
7
|
-
'page-top'?: (props: typeof
|
|
7
|
+
'page-top'?: (props: typeof __VLS_356) => any;
|
|
8
8
|
} & {
|
|
9
|
-
'page-bottom'?: (props: typeof
|
|
9
|
+
'page-bottom'?: (props: typeof __VLS_363) => any;
|
|
10
10
|
};
|
|
11
11
|
declare const __VLS_base: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
12
12
|
logout: (...args: any[]) => void;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
declare var __VLS_38: {},
|
|
1
|
+
declare var __VLS_38: {}, __VLS_245: {}, __VLS_356: {}, __VLS_363: {};
|
|
2
2
|
type __VLS_Slots = {} & {
|
|
3
3
|
header?: (props: typeof __VLS_38) => any;
|
|
4
4
|
} & {
|
|
5
|
-
'user-menu'?: (props: typeof
|
|
5
|
+
'user-menu'?: (props: typeof __VLS_245) => any;
|
|
6
6
|
} & {
|
|
7
|
-
'page-top'?: (props: typeof
|
|
7
|
+
'page-top'?: (props: typeof __VLS_356) => any;
|
|
8
8
|
} & {
|
|
9
|
-
'page-bottom'?: (props: typeof
|
|
9
|
+
'page-bottom'?: (props: typeof __VLS_363) => any;
|
|
10
10
|
};
|
|
11
11
|
declare const __VLS_base: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
12
12
|
logout: (...args: any[]) => void;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { ref, computed, onMounted, onUnmounted } from "vue";
|
|
3
|
+
import { useQuasar } from "quasar";
|
|
4
|
+
import { useLight, q, m, navigateTo } from "#imports";
|
|
5
|
+
const $q = useQuasar();
|
|
6
|
+
const light = useLight();
|
|
7
|
+
const notifications = ref([]);
|
|
8
|
+
const unreadCount = ref(0);
|
|
9
|
+
const loading = ref(false);
|
|
10
|
+
const fetchUnreadCount = async () => {
|
|
11
|
+
try {
|
|
12
|
+
const data = await q({
|
|
13
|
+
my: {
|
|
14
|
+
unreadNotificationCount: true
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
unreadCount.value = data.my.unreadNotificationCount || 0;
|
|
18
|
+
} catch {
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const fetchNotifications = async () => {
|
|
22
|
+
loading.value = true;
|
|
23
|
+
try {
|
|
24
|
+
const data = await q({
|
|
25
|
+
app: {
|
|
26
|
+
listNotification: {
|
|
27
|
+
data: {
|
|
28
|
+
__args: {
|
|
29
|
+
limit: 10,
|
|
30
|
+
offset: 0
|
|
31
|
+
},
|
|
32
|
+
notification_id: true,
|
|
33
|
+
type: true,
|
|
34
|
+
title: true,
|
|
35
|
+
message: true,
|
|
36
|
+
link: true,
|
|
37
|
+
is_read: true,
|
|
38
|
+
created_time: true
|
|
39
|
+
},
|
|
40
|
+
meta: {
|
|
41
|
+
total: true,
|
|
42
|
+
key: true,
|
|
43
|
+
name: true
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
notifications.value = data.app.listNotification.data || [];
|
|
49
|
+
} catch (e) {
|
|
50
|
+
$q.notify({ message: e.message, color: "negative" });
|
|
51
|
+
} finally {
|
|
52
|
+
loading.value = false;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
const markRead = async (notification) => {
|
|
56
|
+
if (notification.is_read) return;
|
|
57
|
+
try {
|
|
58
|
+
await m("markNotificationRead", { id: notification.notification_id });
|
|
59
|
+
notification.is_read = 1;
|
|
60
|
+
unreadCount.value = Math.max(0, unreadCount.value - 1);
|
|
61
|
+
} catch (e) {
|
|
62
|
+
$q.notify({ message: e.message, color: "negative" });
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
const markAllRead = async () => {
|
|
66
|
+
try {
|
|
67
|
+
await m("markAllNotificationsRead");
|
|
68
|
+
notifications.value.forEach((n) => n.is_read = 1);
|
|
69
|
+
unreadCount.value = 0;
|
|
70
|
+
} catch (e) {
|
|
71
|
+
$q.notify({ message: e.message, color: "negative" });
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
const goToInbox = () => {
|
|
75
|
+
navigateTo("/Notification");
|
|
76
|
+
};
|
|
77
|
+
const onClickNotification = (notification) => {
|
|
78
|
+
markRead(notification);
|
|
79
|
+
if (notification.link) {
|
|
80
|
+
navigateTo(notification.link);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
const iconForType = (type) => {
|
|
84
|
+
switch (type) {
|
|
85
|
+
case "success":
|
|
86
|
+
return "sym_o_check_circle";
|
|
87
|
+
case "warning":
|
|
88
|
+
return "sym_o_warning";
|
|
89
|
+
case "error":
|
|
90
|
+
return "sym_o_error";
|
|
91
|
+
default:
|
|
92
|
+
return "sym_o_info";
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
const colorForType = (type) => {
|
|
96
|
+
switch (type) {
|
|
97
|
+
case "success":
|
|
98
|
+
return "positive";
|
|
99
|
+
case "warning":
|
|
100
|
+
return "warning";
|
|
101
|
+
case "error":
|
|
102
|
+
return "negative";
|
|
103
|
+
default:
|
|
104
|
+
return "info";
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
let pollInterval;
|
|
108
|
+
onMounted(() => {
|
|
109
|
+
fetchUnreadCount();
|
|
110
|
+
pollInterval = setInterval(fetchUnreadCount, 6e4);
|
|
111
|
+
});
|
|
112
|
+
onUnmounted(() => {
|
|
113
|
+
if (pollInterval) clearInterval(pollInterval);
|
|
114
|
+
});
|
|
115
|
+
const openDropdown = () => {
|
|
116
|
+
};
|
|
117
|
+
const unreadNotifications = computed(() => notifications.value.filter((n) => !n.is_read));
|
|
118
|
+
const readNotifications = computed(() => notifications.value.filter((n) => n.is_read));
|
|
119
|
+
</script>
|
|
120
|
+
|
|
121
|
+
<template>
|
|
122
|
+
<q-btn dense flat round icon="sym_o_notifications" class="q-mr-xs">
|
|
123
|
+
<q-badge v-if="unreadCount > 0" color="negative" floating rounded>{{ unreadCount > 99 ? '99+' : unreadCount }}</q-badge>
|
|
124
|
+
<q-menu :offset="[0, 8]" max-width="360px" max-height="480px" auto-close @show="fetchNotifications">
|
|
125
|
+
<q-card flat bordered>
|
|
126
|
+
<q-card-section class="row items-center justify-between q-py-sm">
|
|
127
|
+
<div class="text-subtitle2">{{ $t('Notifications') }}</div>
|
|
128
|
+
<q-btn v-if="unreadCount > 0" flat dense size="sm" color="primary" @click="markAllRead">
|
|
129
|
+
{{ $t('Mark all read') }}
|
|
130
|
+
</q-btn>
|
|
131
|
+
</q-card-section>
|
|
132
|
+
<q-separator />
|
|
133
|
+
|
|
134
|
+
<q-card-section v-if="loading" class="text-center q-py-md">
|
|
135
|
+
<q-spinner color="primary" size="2em" />
|
|
136
|
+
</q-card-section>
|
|
137
|
+
|
|
138
|
+
<q-list v-else-if="notifications.length" padding dense separator>
|
|
139
|
+
<template v-if="unreadNotifications.length">
|
|
140
|
+
<q-item-label header class="text-caption text-uppercase text-grey">{{ $t('Unread') }}</q-item-label>
|
|
141
|
+
<q-item v-for="n in unreadNotifications" :key="n.notification_id" clickable v-ripple
|
|
142
|
+
class="bg-blue-1" @click="onClickNotification(n)">
|
|
143
|
+
<q-item-section avatar top>
|
|
144
|
+
<q-icon :name="iconForType(n.type)" :color="colorForType(n.type)" size="24px" />
|
|
145
|
+
</q-item-section>
|
|
146
|
+
<q-item-section>
|
|
147
|
+
<q-item-label class="text-weight-bold">{{ n.title }}</q-item-label>
|
|
148
|
+
<q-item-label caption lines="2">{{ n.message }}</q-item-label>
|
|
149
|
+
<q-item-label caption class="text-grey">{{ n.created_time }}</q-item-label>
|
|
150
|
+
</q-item-section>
|
|
151
|
+
<q-item-section side>
|
|
152
|
+
<q-btn flat round dense icon="sym_o_done" size="sm" color="primary"
|
|
153
|
+
@click.stop="markRead(n)">
|
|
154
|
+
<q-tooltip>{{ $t('Mark as read') }}</q-tooltip>
|
|
155
|
+
</q-btn>
|
|
156
|
+
</q-item-section>
|
|
157
|
+
</q-item>
|
|
158
|
+
</template>
|
|
159
|
+
|
|
160
|
+
<template v-if="readNotifications.length">
|
|
161
|
+
<q-item-label header class="text-caption text-uppercase text-grey">{{ $t('Earlier') }}</q-item-label>
|
|
162
|
+
<q-item v-for="n in readNotifications" :key="n.notification_id" clickable v-ripple
|
|
163
|
+
@click="onClickNotification(n)">
|
|
164
|
+
<q-item-section avatar top>
|
|
165
|
+
<q-icon :name="iconForType(n.type)" color="grey" size="24px" />
|
|
166
|
+
</q-item-section>
|
|
167
|
+
<q-item-section>
|
|
168
|
+
<q-item-label>{{ n.title }}</q-item-label>
|
|
169
|
+
<q-item-label caption lines="2">{{ n.message }}</q-item-label>
|
|
170
|
+
<q-item-label caption class="text-grey">{{ n.created_time }}</q-item-label>
|
|
171
|
+
</q-item-section>
|
|
172
|
+
</q-item>
|
|
173
|
+
</template>
|
|
174
|
+
</q-list>
|
|
175
|
+
|
|
176
|
+
<q-card-section v-else class="text-center text-grey q-py-md">
|
|
177
|
+
{{ $t('No notifications') }}
|
|
178
|
+
</q-card-section>
|
|
179
|
+
|
|
180
|
+
<q-separator />
|
|
181
|
+
<q-card-actions align="center">
|
|
182
|
+
<q-btn flat color="primary" size="sm" @click="goToInbox">{{ $t('View all notifications') }}</q-btn>
|
|
183
|
+
</q-card-actions>
|
|
184
|
+
</q-card>
|
|
185
|
+
</q-menu>
|
|
186
|
+
</q-btn>
|
|
187
|
+
</template>
|
|
@@ -79,17 +79,23 @@ export interface LTableRequest {
|
|
|
79
79
|
}) => void;
|
|
80
80
|
}
|
|
81
81
|
declare function requestServerInteraction(): void;
|
|
82
|
-
declare var
|
|
82
|
+
declare var __VLS_24: {
|
|
83
|
+
props: any;
|
|
84
|
+
}, __VLS_55: any, __VLS_119: any, __VLS_122: string, __VLS_123: any, __VLS_154: any, __VLS_157: any, __VLS_327: string, __VLS_328: any;
|
|
83
85
|
type __VLS_Slots = {} & {
|
|
84
|
-
[K in NonNullable<typeof
|
|
86
|
+
[K in NonNullable<typeof __VLS_122>]?: (props: typeof __VLS_123) => any;
|
|
85
87
|
} & {
|
|
86
|
-
[K in NonNullable<typeof
|
|
88
|
+
[K in NonNullable<typeof __VLS_327>]?: (props: typeof __VLS_328) => any;
|
|
87
89
|
} & {
|
|
88
|
-
|
|
90
|
+
'header-selection'?: (props: typeof __VLS_24) => any;
|
|
89
91
|
} & {
|
|
90
|
-
'
|
|
92
|
+
'top-selection'?: (props: typeof __VLS_55) => any;
|
|
91
93
|
} & {
|
|
92
|
-
|
|
94
|
+
actions?: (props: typeof __VLS_119) => any;
|
|
95
|
+
} & {
|
|
96
|
+
'row-expand'?: (props: typeof __VLS_154) => any;
|
|
97
|
+
} & {
|
|
98
|
+
'top-right'?: (props: typeof __VLS_157) => any;
|
|
93
99
|
};
|
|
94
100
|
declare const __VLS_base: import("vue").DefineComponent<LTableProps, {
|
|
95
101
|
requestServerInteraction: typeof requestServerInteraction;
|
|
@@ -562,7 +562,9 @@ const hasFilters = computed(() => {
|
|
|
562
562
|
<template #header="props">
|
|
563
563
|
<q-tr :props="props">
|
|
564
564
|
<q-th v-if="selection != 'none'" auto-width>
|
|
565
|
-
<
|
|
565
|
+
<slot name="header-selection" :props="props">
|
|
566
|
+
<q-checkbox v-model="props.selected" :dense="table?.dense" />
|
|
567
|
+
</slot>
|
|
566
568
|
</q-th>
|
|
567
569
|
<q-th v-if="hasRowExpand" auto-width></q-th>
|
|
568
570
|
<q-th v-if="hasActions" auto-width></q-th>
|
|
@@ -578,6 +580,10 @@ const hasFilters = computed(() => {
|
|
|
578
580
|
</div>
|
|
579
581
|
</template>
|
|
580
582
|
|
|
583
|
+
<template #top-selection="props" v-if="ss.indexOf('top-selection') >= 0">
|
|
584
|
+
<slot name="top-selection" v-bind="props"></slot>
|
|
585
|
+
</template>
|
|
586
|
+
|
|
581
587
|
<template #top-left v-if="addComponent">
|
|
582
588
|
<q-btn icon="sym_o_add" :label="$t('Add')" color="primary" @click="onAdd" outline />
|
|
583
589
|
</template>
|
|
@@ -79,17 +79,23 @@ export interface LTableRequest {
|
|
|
79
79
|
}) => void;
|
|
80
80
|
}
|
|
81
81
|
declare function requestServerInteraction(): void;
|
|
82
|
-
declare var
|
|
82
|
+
declare var __VLS_24: {
|
|
83
|
+
props: any;
|
|
84
|
+
}, __VLS_55: any, __VLS_119: any, __VLS_122: string, __VLS_123: any, __VLS_154: any, __VLS_157: any, __VLS_327: string, __VLS_328: any;
|
|
83
85
|
type __VLS_Slots = {} & {
|
|
84
|
-
[K in NonNullable<typeof
|
|
86
|
+
[K in NonNullable<typeof __VLS_122>]?: (props: typeof __VLS_123) => any;
|
|
85
87
|
} & {
|
|
86
|
-
[K in NonNullable<typeof
|
|
88
|
+
[K in NonNullable<typeof __VLS_327>]?: (props: typeof __VLS_328) => any;
|
|
87
89
|
} & {
|
|
88
|
-
|
|
90
|
+
'header-selection'?: (props: typeof __VLS_24) => any;
|
|
89
91
|
} & {
|
|
90
|
-
'
|
|
92
|
+
'top-selection'?: (props: typeof __VLS_55) => any;
|
|
91
93
|
} & {
|
|
92
|
-
|
|
94
|
+
actions?: (props: typeof __VLS_119) => any;
|
|
95
|
+
} & {
|
|
96
|
+
'row-expand'?: (props: typeof __VLS_154) => any;
|
|
97
|
+
} & {
|
|
98
|
+
'top-right'?: (props: typeof __VLS_157) => any;
|
|
93
99
|
};
|
|
94
100
|
declare const __VLS_base: import("vue").DefineComponent<LTableProps, {
|
|
95
101
|
requestServerInteraction: typeof requestServerInteraction;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { defineLightModel } from "#imports";
|
|
2
|
+
export default defineLightModel({
|
|
3
|
+
name: "Notification",
|
|
4
|
+
dataPath: "app.listNotification",
|
|
5
|
+
fields: {
|
|
6
|
+
notification_id: {
|
|
7
|
+
label: "ID",
|
|
8
|
+
sortable: true
|
|
9
|
+
},
|
|
10
|
+
type: {
|
|
11
|
+
label: "Type",
|
|
12
|
+
sortable: true,
|
|
13
|
+
searchable: true,
|
|
14
|
+
searchType: "select",
|
|
15
|
+
searchOptions: [
|
|
16
|
+
{ label: "Info", value: "info" },
|
|
17
|
+
{ label: "Success", value: "success" },
|
|
18
|
+
{ label: "Warning", value: "warning" },
|
|
19
|
+
{ label: "Error", value: "error" }
|
|
20
|
+
],
|
|
21
|
+
format: (value) => {
|
|
22
|
+
const map = { info: "Info", success: "Success", warning: "Warning", error: "Error" };
|
|
23
|
+
return map[value] || value;
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
title: {
|
|
27
|
+
label: "Title",
|
|
28
|
+
sortable: true,
|
|
29
|
+
searchable: true
|
|
30
|
+
},
|
|
31
|
+
message: {
|
|
32
|
+
label: "Message",
|
|
33
|
+
searchable: true
|
|
34
|
+
},
|
|
35
|
+
link: {
|
|
36
|
+
label: "Link"
|
|
37
|
+
},
|
|
38
|
+
is_read: {
|
|
39
|
+
label: "Read",
|
|
40
|
+
sortable: true,
|
|
41
|
+
searchable: true,
|
|
42
|
+
searchType: "boolean",
|
|
43
|
+
format: (value) => value ? "Yes" : "No"
|
|
44
|
+
},
|
|
45
|
+
created_time: {
|
|
46
|
+
label: "Created Time",
|
|
47
|
+
sortable: true,
|
|
48
|
+
searchable: true,
|
|
49
|
+
searchType: "date"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { ref } from "vue";
|
|
3
|
+
import { useQuasar } from "quasar";
|
|
4
|
+
import { model, m, notify } from "#imports";
|
|
5
|
+
const $q = useQuasar();
|
|
6
|
+
const tableRef = ref(null);
|
|
7
|
+
const selected = ref([]);
|
|
8
|
+
const columns = model("Notification").columns({
|
|
9
|
+
notification_id: true,
|
|
10
|
+
type: true,
|
|
11
|
+
title: true,
|
|
12
|
+
message: true,
|
|
13
|
+
link: true,
|
|
14
|
+
is_read: true,
|
|
15
|
+
created_time: true
|
|
16
|
+
});
|
|
17
|
+
const onBulkDelete = async () => {
|
|
18
|
+
if (selected.value.length === 0) return;
|
|
19
|
+
$q.dialog({
|
|
20
|
+
title: $q.lang.label?.delete || "Delete",
|
|
21
|
+
message: "Are you sure you want to delete " + selected.value.length + " selected notification(s)?",
|
|
22
|
+
cancel: true,
|
|
23
|
+
persistent: true,
|
|
24
|
+
color: "negative"
|
|
25
|
+
}).onOk(async () => {
|
|
26
|
+
try {
|
|
27
|
+
const ids = selected.value.map((n) => n.notification_id);
|
|
28
|
+
await m("deleteNotifications", { ids });
|
|
29
|
+
notify("Deleted " + ids.length + " notification(s)");
|
|
30
|
+
selected.value = [];
|
|
31
|
+
tableRef.value?.requestServerInteraction();
|
|
32
|
+
} catch (e) {
|
|
33
|
+
notify({ message: e.message, color: "negative" });
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
const onDelete = () => {
|
|
38
|
+
tableRef.value?.requestServerInteraction();
|
|
39
|
+
};
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<template>
|
|
43
|
+
<l-page>
|
|
44
|
+
<l-table ref="tableRef" row-key="notification_id" :columns="columns"
|
|
45
|
+
selection="multiple" v-model:selected="selected"
|
|
46
|
+
@request-data="$event.loadObjects('Notification')"
|
|
47
|
+
:actions="['delete']"
|
|
48
|
+
@delete="onDelete">
|
|
49
|
+
<template #top-selection="{ rows }">
|
|
50
|
+
<q-btn flat dense color="negative" icon="sym_o_delete"
|
|
51
|
+
:label="'Delete (' + selected.length + ')'" @click="onBulkDelete" />
|
|
52
|
+
</template>
|
|
53
|
+
</l-table>
|
|
54
|
+
</l-page>
|
|
55
|
+
</template>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
declare const _default: typeof __VLS_export;
|
|
2
|
+
export default _default;
|
|
3
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
declare const _default: typeof __VLS_export;
|
|
2
|
+
export default _default;
|
|
3
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
declare const _default: typeof __VLS_export;
|
|
2
|
+
export default _default;
|
|
3
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
declare const _default: typeof __VLS_export;
|
|
2
|
+
export default _default;
|
|
3
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
package/package.json
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/dist/runtime/pages/{Role/_name/update-child.d.vue.ts → Notification/index.d.vue.ts}
RENAMED
|
File without changes
|
/package/dist/runtime/pages/{Role/_name/update-child.vue.d.ts → Notification/index.vue.d.ts}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|