@things-factory/shell 7.0.1-alpha.1 → 7.0.1-alpha.100
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/_index.html +6 -2
- package/client/entries/public/home.js +5 -6
- package/client/index.js +1 -6
- package/client/route.js +11 -0
- package/client/themes/app-theme.css +26 -4
- package/client/themes/layout-theme.css +2 -2
- package/client/themes/material-theme.css +50 -0
- package/client/themes/md-typescale-styles.css +100 -0
- package/dist-server/server-dev.js +2 -6
- package/dist-server/server-dev.js.map +1 -1
- package/dist-server/server.js +1 -0
- package/dist-server/server.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/dist-server/typeorm/round-transform.js +1 -1
- package/dist-server/typeorm/round-transform.js.map +1 -1
- package/package.json +10 -10
- package/server/server-dev.ts +9 -10
- package/server/server.ts +8 -1
- package/server/typeorm/round-transform.ts +1 -1
- package/translations/en.json +2 -1
- package/translations/ja.json +2 -1
- package/translations/ko.json +2 -1
- package/translations/ms.json +2 -1
- package/translations/zh.json +2 -1
- package/views/public/home.html +4 -2
- package/views/template.html +2 -2
- package/client/elements/custom-alert.js +0 -120
- package/client/elements/index.js +0 -4
- package/client/elements/oops-note.js +0 -49
- package/client/elements/oops-progress.js +0 -81
- package/client/elements/oops-spinner.js +0 -31
- package/helps/components/oops-progress.md +0 -73
@@ -10,7 +10,7 @@ exports.roundTransformer = {
|
|
10
10
|
* @param {number | null} value - Floating point value to round or null
|
11
11
|
* @returns {number | null} - Rounded number or null
|
12
12
|
*/
|
13
|
-
to: (value) => (value !== null && !isNaN(value) ? Math.round(value *
|
13
|
+
to: (value) => (value !== null && !isNaN(value) ? Math.round(value * 10000) / 10000 : undefined),
|
14
14
|
/**
|
15
15
|
* Returns the entity field value as it is without any transformation when reading from the database.
|
16
16
|
* @param {number} value - Number value read from the database
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"round-transform.js","sourceRoot":"","sources":["../../server/typeorm/round-transform.ts"],"names":[],"mappings":";;;AAEA;;GAEG;AACU,QAAA,gBAAgB,GAAqB;IAChD;;;;OAIG;IACH,EAAE,EAAE,CAAC,KAAoB,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,
|
1
|
+
{"version":3,"file":"round-transform.js","sourceRoot":"","sources":["../../server/typeorm/round-transform.ts"],"names":[],"mappings":";;;AAEA;;GAEG;AACU,QAAA,gBAAgB,GAAqB;IAChD;;;;OAIG;IACH,EAAE,EAAE,CAAC,KAAoB,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAE/G;;;;OAIG;IACH,IAAI,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK;CAC/B,CAAA","sourcesContent":["import { ValueTransformer } from 'typeorm'\n\n/**\n * ValueTransformer object for rounding floating point values.\n */\nexport const roundTransformer: ValueTransformer = {\n /**\n * Rounds the entity field value before storing it in the database.\n * @param {number | null} value - Floating point value to round or null\n * @returns {number | null} - Rounded number or null\n */\n to: (value: number | null) => (value !== null && !isNaN(value) ? Math.round(value * 10000) / 10000 : undefined),\n\n /**\n * Returns the entity field value as it is without any transformation when reading from the database.\n * @param {number} value - Number value read from the database\n * @returns {number} - The number value as is\n */\n from: (value: number) => value\n}\n"]}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@things-factory/shell",
|
3
|
-
"version": "7.0.1-alpha.
|
3
|
+
"version": "7.0.1-alpha.100",
|
4
4
|
"description": "Core module for framework",
|
5
5
|
"bin": {
|
6
6
|
"things-factory": "bin/things-factory",
|
@@ -46,12 +46,11 @@
|
|
46
46
|
"@koa/cors": "^5.0.0",
|
47
47
|
"@material-design-icons/font": "^0.14.9",
|
48
48
|
"@material/mwc-button": "^0.27.0",
|
49
|
-
"@material/mwc-fab": "^0.27.0",
|
50
49
|
"@material/mwc-icon": "^0.27.0",
|
51
50
|
"@material/mwc-icon-button": "^0.27.0",
|
52
51
|
"@material/mwc-slider": "^0.27.0",
|
53
52
|
"@material/mwc-textfield": "^0.27.0",
|
54
|
-
"@material/web": "^1.
|
53
|
+
"@material/web": "^1.4.0",
|
55
54
|
"@open-wc/scoped-elements": "^2.1.3",
|
56
55
|
"@operato/board": "^2.0.0-alpha.0",
|
57
56
|
"@operato/graphql": "^2.0.0-alpha.0",
|
@@ -60,11 +59,12 @@
|
|
60
59
|
"@operato/shell": "^2.0.0-alpha.0",
|
61
60
|
"@operato/typeorm-history": "^2.0.0-alpha.0",
|
62
61
|
"@operato/utils": "^2.0.0-alpha.0",
|
63
|
-
"@things-factory/ejs-remote": "^7.0.1-alpha.
|
64
|
-
"@things-factory/env": "^7.0.1-alpha.
|
62
|
+
"@things-factory/ejs-remote": "^7.0.1-alpha.71",
|
63
|
+
"@things-factory/env": "^7.0.1-alpha.71",
|
65
64
|
"@things-factory/operato-license-checker": "^4.0.4",
|
66
|
-
"@things-factory/styles": "^7.0.1-alpha.
|
67
|
-
"@things-factory/utils": "^7.0.1-alpha.
|
65
|
+
"@things-factory/styles": "^7.0.1-alpha.71",
|
66
|
+
"@things-factory/utils": "^7.0.1-alpha.71",
|
67
|
+
"@webcomponents/scoped-custom-element-registry": "^0.0.9",
|
68
68
|
"@webcomponents/webcomponentsjs": "^2.6.0",
|
69
69
|
"args": "^5.0.0",
|
70
70
|
"broadcastchannel-polyfill": "^1.0.1",
|
@@ -97,10 +97,11 @@
|
|
97
97
|
"koa-send": "^5.0.0",
|
98
98
|
"koa-static": "^5.0.0",
|
99
99
|
"koa2-connect-history-api-fallback": "^0.1.2",
|
100
|
-
"lit": "^
|
100
|
+
"lit": "^3.1.2",
|
101
101
|
"loader-utils": "^2.0.0",
|
102
102
|
"lodash": "^4.17.21",
|
103
103
|
"lodash-es": "^4.17.21",
|
104
|
+
"material-symbols": "^0.17.2",
|
104
105
|
"mkdirp": "^1.0.4",
|
105
106
|
"moment-timezone": "^0.5.43",
|
106
107
|
"mqtt": "^4.3.4",
|
@@ -118,7 +119,6 @@
|
|
118
119
|
"reselect": "^4.0.0",
|
119
120
|
"sass": "^1.50.1",
|
120
121
|
"scrollbooster": "^3.0.2",
|
121
|
-
"sweetalert2": "^11.7.3",
|
122
122
|
"type-graphql": "^2.0.0-beta.6",
|
123
123
|
"typeorm": "^0.3.19",
|
124
124
|
"uuid": "^3.4.0",
|
@@ -134,5 +134,5 @@
|
|
134
134
|
"pg": "^8.7.3",
|
135
135
|
"sqlite3": "^5.0.8"
|
136
136
|
},
|
137
|
-
"gitHead": "
|
137
|
+
"gitHead": "f5062c5559383d06fc8f9f870b56163952557c70"
|
138
138
|
}
|
package/server/server-dev.ts
CHANGED
@@ -20,7 +20,6 @@ import { useServer } from 'graphql-ws/lib/use/ws'
|
|
20
20
|
import { createServer } from 'http'
|
21
21
|
import Koa from 'koa'
|
22
22
|
import koaBodyParser from 'koa-bodyparser'
|
23
|
-
import koaStatic from 'koa-static'
|
24
23
|
import compose from 'koa-compose'
|
25
24
|
import { historyApiFallback } from 'koa2-connect-history-api-fallback'
|
26
25
|
import { WebSocketServer } from 'ws'
|
@@ -34,7 +33,13 @@ import { initLicense, checkValidity } from '@things-factory/operato-license-chec
|
|
34
33
|
|
35
34
|
import { GraphqlLocalClient } from './graphql-local-client'
|
36
35
|
import { databaseInitializer } from './initializers/database'
|
37
|
-
import {
|
36
|
+
import {
|
37
|
+
domainPrivateRouter,
|
38
|
+
domainPublicRouter,
|
39
|
+
globalPrivateRouter,
|
40
|
+
globalPublicRouter,
|
41
|
+
graphqlRouter
|
42
|
+
} from './routers'
|
38
43
|
import { schema } from './schema'
|
39
44
|
import { Domain } from './service'
|
40
45
|
import { EntityManager } from 'typeorm'
|
@@ -59,7 +64,6 @@ args.option('webpack', 'webpack configuration file', config.get('webpack'))
|
|
59
64
|
|
60
65
|
const flags = args.parse(process.argv)
|
61
66
|
|
62
|
-
const path = require('path')
|
63
67
|
const webpack = require('webpack')
|
64
68
|
const webpackConfig = require(flags.webpack || '@things-factory/builder/webpack.config.dev.js')
|
65
69
|
|
@@ -99,6 +103,7 @@ const bootstrap = async () => {
|
|
99
103
|
await databaseInitializer()
|
100
104
|
|
101
105
|
const app = new Koa<ICustomAppState, ICustomAppContext>() as any
|
106
|
+
app.proxy = true
|
102
107
|
|
103
108
|
app.use(
|
104
109
|
cors({
|
@@ -269,17 +274,11 @@ const bootstrap = async () => {
|
|
269
274
|
app.use(graphqlRouter.routes())
|
270
275
|
app.use(graphqlRouter.allowedMethods())
|
271
276
|
|
272
|
-
/* should follow this order : history-fallback => webpack-middleware
|
277
|
+
/* should follow this order : history-fallback => webpack-middleware */
|
273
278
|
app.use(historyApiFallback({ whiteList: [] }))
|
274
279
|
|
275
280
|
app.use(middleware)
|
276
281
|
|
277
|
-
app.use(
|
278
|
-
koaStatic(compiler.outputPath, {
|
279
|
-
index: false
|
280
|
-
})
|
281
|
-
)
|
282
|
-
|
283
282
|
httpServer.listen({ port: PORT }, () => {
|
284
283
|
logger.info(`🚀 Server ready at http://0.0.0.0:${PORT}/graphql`)
|
285
284
|
logger.info(`🚀 Subscriptions ready at ws://0.0.0.0:${PORT}/graphql`)
|
package/server/server.ts
CHANGED
@@ -33,7 +33,13 @@ import { initLicense, checkValidity } from '@things-factory/operato-license-chec
|
|
33
33
|
|
34
34
|
import { GraphqlLocalClient } from './graphql-local-client'
|
35
35
|
import { databaseInitializer } from './initializers/database'
|
36
|
-
import {
|
36
|
+
import {
|
37
|
+
domainPrivateRouter,
|
38
|
+
domainPublicRouter,
|
39
|
+
globalPrivateRouter,
|
40
|
+
globalPublicRouter,
|
41
|
+
graphqlRouter
|
42
|
+
} from './routers'
|
37
43
|
import { schema } from './schema'
|
38
44
|
import { domainMiddleware } from './middlewares'
|
39
45
|
|
@@ -74,6 +80,7 @@ const bootstrap = async () => {
|
|
74
80
|
await databaseInitializer()
|
75
81
|
|
76
82
|
const app = new Koa() as any
|
83
|
+
app.proxy = true
|
77
84
|
|
78
85
|
app.use(
|
79
86
|
cors({
|
@@ -9,7 +9,7 @@ export const roundTransformer: ValueTransformer = {
|
|
9
9
|
* @param {number | null} value - Floating point value to round or null
|
10
10
|
* @returns {number | null} - Rounded number or null
|
11
11
|
*/
|
12
|
-
to: (value: number | null) => (value !== null && !isNaN(value) ? Math.round(value *
|
12
|
+
to: (value: number | null) => (value !== null && !isNaN(value) ? Math.round(value * 10000) / 10000 : undefined),
|
13
13
|
|
14
14
|
/**
|
15
15
|
* Returns the entity field value as it is without any transformation when reading from the database.
|
package/translations/en.json
CHANGED
@@ -29,5 +29,6 @@
|
|
29
29
|
"text.nothing_changed": "nothing changed",
|
30
30
|
"text.nothing_selected": "nothing selected",
|
31
31
|
"text.there_is_nothing_to_delete": "there is nothing to delete",
|
32
|
-
"text.there_is_nothing_to_save": "there is nothing to save"
|
32
|
+
"text.there_is_nothing_to_save": "there is nothing to save",
|
33
|
+
"text.column visibility setting": "column visibility"
|
33
34
|
}
|
package/translations/ja.json
CHANGED
@@ -28,5 +28,6 @@
|
|
28
28
|
"text.nothing_changed": "変更なし",
|
29
29
|
"text.nothing_selected": "選択されていない",
|
30
30
|
"text.there_is_nothing_to_delete": "削除するデータがありません.",
|
31
|
-
"text.there_is_nothing_to_save": "保存するデータがありません."
|
31
|
+
"text.there_is_nothing_to_save": "保存するデータがありません.",
|
32
|
+
"text.column visibility setting": "カラムの表示設定"
|
32
33
|
}
|
package/translations/ko.json
CHANGED
@@ -28,5 +28,6 @@
|
|
28
28
|
"text.nothing_changed": "변경사항 없음",
|
29
29
|
"text.nothing_selected": "선택되지 않음",
|
30
30
|
"text.there_is_nothing_to_delete": "삭제할 데이터가 없습니다.",
|
31
|
-
"text.there_is_nothing_to_save": "저장할 데이터가 없습니다."
|
31
|
+
"text.there_is_nothing_to_save": "저장할 데이터가 없습니다.",
|
32
|
+
"text.column visibility setting": "컬럼 보이기"
|
32
33
|
}
|
package/translations/ms.json
CHANGED
@@ -28,5 +28,6 @@
|
|
28
28
|
"text.nothing_changed": "nothing changed",
|
29
29
|
"text.nothing_selected": "nothing selected",
|
30
30
|
"text.there_is_nothing_to_delete": "there is nothing to delete",
|
31
|
-
"text.there_is_nothing_to_save": "there is nothing to save"
|
31
|
+
"text.there_is_nothing_to_save": "there is nothing to save",
|
32
|
+
"text.column visibility setting": "tetapan kebolehlihatan kolum"
|
32
33
|
}
|
package/translations/zh.json
CHANGED
@@ -28,5 +28,6 @@
|
|
28
28
|
"text.nothing_changed": "无更改",
|
29
29
|
"text.nothing_selected": "未选择",
|
30
30
|
"text.there_is_nothing_to_delete": "没有要删除的数据。",
|
31
|
-
"text.there_is_nothing_to_save": "没有要保存的数据。"
|
31
|
+
"text.there_is_nothing_to_save": "没有要保存的数据。",
|
32
|
+
"text.column visibility setting": "列显示"
|
32
33
|
}
|
package/views/public/home.html
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
<!
|
1
|
+
<!doctype html>
|
2
2
|
<html lang="en">
|
3
3
|
<head>
|
4
4
|
<meta charset="utf-8" />
|
@@ -52,6 +52,8 @@
|
|
52
52
|
<!-- Performance tip: hint to the browser to start the handshake for the fonts site -->
|
53
53
|
<link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin />
|
54
54
|
<link href="/node_modules/@material-design-icons/font/index.css" rel="stylesheet" />
|
55
|
+
<link href="/node_modules/material-symbols/index.css" rel="stylesheet" />
|
56
|
+
<link href="/node_modules/@fontsource/roboto/index.css" rel="stylesheet" />
|
55
57
|
<link rel="stylesheet" href="/theme.css" />
|
56
58
|
|
57
59
|
<style>
|
@@ -81,7 +83,7 @@
|
|
81
83
|
<link rel="prefetch" href="/public/home.js" />
|
82
84
|
</head>
|
83
85
|
|
84
|
-
<body>
|
86
|
+
<body class="light">
|
85
87
|
<home-page id="page"></home-page>
|
86
88
|
<noscript> Please enable JavaScript to view this website. </noscript>
|
87
89
|
<!-- Load webcomponents-loader.js to check and load any polyfills your browser needs -->
|
package/views/template.html
CHANGED
@@ -1,120 +0,0 @@
|
|
1
|
-
import Swal from 'sweetalert2'
|
2
|
-
|
3
|
-
/**
|
4
|
-
* Custom Alert utilized sweetalert2 to produce a simple pop-up message box.
|
5
|
-
* *Side note: Did not fully utilize sweet alert capability, just added some common usage.
|
6
|
-
* @param {string} type - ['success', 'error', 'warning', 'info', 'question']
|
7
|
-
* @param {string} icon - ['success', 'error', 'warning', 'info', 'question']
|
8
|
-
* @param {string} title - Title for the message box.
|
9
|
-
* @param {string} text - Description for the message box. Input can be in html format.
|
10
|
-
* @param {string} footer - Footer message. Input can be in html format
|
11
|
-
* @param {string} [position = 'center'] - Position of the message box. ['top', 'top-start', 'top-end', 'center', 'center-start', 'center-end', 'bottom', 'bottom-start', 'bottom-end']
|
12
|
-
* @param {boolean} toast - Set to 'True' to display as toast.
|
13
|
-
* @param {object} confirmButton - Confirm button is an object type. The text and color of the button can be changed by adding 'text' or 'color' property into the object.
|
14
|
-
* text is the required field of the object. When the object is populated, the confirm button will automatically shown.
|
15
|
-
* @param {object} cancelButton - Cancel button is an object type. The text and color of the button can be changed by adding 'text' or 'color' property into the object.
|
16
|
-
* text is the required field of the object. When the object is populated, the cancel button will automatically shown.
|
17
|
-
* @param {boolean} [invertButton = false] - Invert button to swap the position of the buttons.
|
18
|
-
* eg. Confirm button on the right, Cancel button on the left.
|
19
|
-
* @param {function} callback - Accepts a function with an input parameter. Will invoked after swal.fire. It is a promise chaining function.
|
20
|
-
* @param {function} onBeforeOpen - Accepts a function with no parameter. Function to run when modal built, but not shown yet. Provides modal DOM element as the first argument.
|
21
|
-
* @param {function} onOpen - Accepts a function with no parameter. Function to run when modal opens, provides modal DOM element as the first argument.
|
22
|
-
* @param {function} onRender - Accepts a function with no parameter. Function to run after modal DOM has been updated. eg. After Swal.fire() or Swal.update()
|
23
|
-
* @param {function} onClose - Accepts a function with no parameter. Function to run when modal closes, provides modal DOM element as the first argument.
|
24
|
-
* @param {function} onAfterClose - Accepts a function with no parameter. Function to run after modal has been disposed.
|
25
|
-
* @param {boolean} [debug = false] - Check all parameters are set properly. When set to 'true', simple checking will be done on the input parameters to verify the type.
|
26
|
-
*/
|
27
|
-
|
28
|
-
export async function CustomAlert({
|
29
|
-
type = 'info',
|
30
|
-
icon,
|
31
|
-
title,
|
32
|
-
text,
|
33
|
-
allowOutsideClick = true,
|
34
|
-
allowEscapeKey = true,
|
35
|
-
footer,
|
36
|
-
position = 'center',
|
37
|
-
toast,
|
38
|
-
timer,
|
39
|
-
confirmButton = {},
|
40
|
-
cancelButton = {},
|
41
|
-
invertButton = false,
|
42
|
-
callback,
|
43
|
-
onBeforeOpen,
|
44
|
-
onOpen,
|
45
|
-
onRender,
|
46
|
-
onClose,
|
47
|
-
onAfterClose,
|
48
|
-
debug = false
|
49
|
-
}) {
|
50
|
-
try {
|
51
|
-
if (debug) {
|
52
|
-
let arrTypes = ['success', 'error', 'warning', 'info', 'question']
|
53
|
-
let err = ''
|
54
|
-
if (!arrTypes.includes(type)) {
|
55
|
-
err = err + 'Invalid Alert Type.\n'
|
56
|
-
}
|
57
|
-
|
58
|
-
if (title && typeof title !== 'string') err = err + 'Invalid Title.\n'
|
59
|
-
if (text && typeof text !== 'string') err = err + 'Invalid Text.\n'
|
60
|
-
if (footer && typeof text !== 'string') err = err + 'Invalid Footer.\n'
|
61
|
-
if (typeof position !== 'string') err = err + 'Invalid Position.\n'
|
62
|
-
if (toast && typeof toast !== 'boolean') err = err + 'Invalid Footer.\n'
|
63
|
-
if (
|
64
|
-
Object.keys(confirmButton).length > 0 &&
|
65
|
-
(typeof confirmButton !== 'object' || !confirmButton.hasOwnProperty('text'))
|
66
|
-
)
|
67
|
-
err = err + 'Invalid Confirm Button.\n'
|
68
|
-
if (
|
69
|
-
Object.keys(cancelButton).length > 0 &&
|
70
|
-
(typeof cancelButton !== 'object' || !cancelButton.hasOwnProperty('text'))
|
71
|
-
)
|
72
|
-
err = err + 'Invalid Cancel Button.\n'
|
73
|
-
|
74
|
-
if (err !== '') throw new Error(err)
|
75
|
-
}
|
76
|
-
|
77
|
-
const result = await Swal.fire({
|
78
|
-
icon: icon || type,
|
79
|
-
title: title,
|
80
|
-
text: text,
|
81
|
-
timer: timer ? timer:0,
|
82
|
-
timerProgressBar: timer ? true : 0,
|
83
|
-
allowOutsideClick: allowOutsideClick,
|
84
|
-
allowEscapeKey: allowEscapeKey,
|
85
|
-
footer: footer,
|
86
|
-
position: position,
|
87
|
-
showConfirmButton: Object.keys(confirmButton).length > 0 ? true : false,
|
88
|
-
showCancelButton: Object.keys(cancelButton).length > 0 ? true : false,
|
89
|
-
confirmButtonText: confirmButton.hasOwnProperty('text') ? confirmButton.text : 'confirm',
|
90
|
-
cancelButtonText: cancelButton.hasOwnProperty('text') ? cancelButton.text : 'cancel',
|
91
|
-
confirmButtonColor: confirmButton.hasOwnProperty('color') ? confirmButton.color : '#22a6a7',
|
92
|
-
cancelButtonColor: cancelButton.hasOwnProperty('color') ? cancelButton.color : '#cfcfcf',
|
93
|
-
toast: toast,
|
94
|
-
reverseButtons: invertButton,
|
95
|
-
willOpen: () => {
|
96
|
-
onBeforeOpen ? onBeforeOpen() : undefined
|
97
|
-
},
|
98
|
-
didOpen: () => {
|
99
|
-
onOpen ? onOpen() : undefined
|
100
|
-
},
|
101
|
-
didRender: () => {
|
102
|
-
onRender ? onRender() : undefined
|
103
|
-
},
|
104
|
-
willClose: () => {
|
105
|
-
onClose ? onClose() : undefined
|
106
|
-
},
|
107
|
-
didClose: () => {
|
108
|
-
onAfterClose ? onAfterClose() : undefined
|
109
|
-
}
|
110
|
-
})
|
111
|
-
|
112
|
-
if (callback && typeof callback === 'function') {
|
113
|
-
callback(result)
|
114
|
-
} else {
|
115
|
-
return Promise.resolve(result)
|
116
|
-
}
|
117
|
-
} catch (error) {
|
118
|
-
console.log('%c(Custom-Alert)\n' + error, 'color:Red')
|
119
|
-
}
|
120
|
-
}
|
package/client/elements/index.js
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
import { LitElement, html, css } from 'lit'
|
2
|
-
|
3
|
-
import '@material/mwc-icon'
|
4
|
-
|
5
|
-
export class OopsNote extends LitElement {
|
6
|
-
static get styles() {
|
7
|
-
return css`
|
8
|
-
:host {
|
9
|
-
display: block;
|
10
|
-
text-align: center;
|
11
|
-
}
|
12
|
-
mwc-icon {
|
13
|
-
font: var(--oops-note-icon-font);
|
14
|
-
color: var(--oops-note-icon-color);
|
15
|
-
border: var(--oops-note-icon-border);
|
16
|
-
border-radius: var(--oops-note-icon-border-radius);
|
17
|
-
padding: var(--oops-note-icon-padding);
|
18
|
-
}
|
19
|
-
[title] {
|
20
|
-
margin: var(--oops-note-title-margin);
|
21
|
-
font: var(--oops-note-title-font);
|
22
|
-
color: var(--oops-note-title-color);
|
23
|
-
text-transform: capitalize;
|
24
|
-
}
|
25
|
-
[description] {
|
26
|
-
font: var(--oops-note-description-font);
|
27
|
-
color: var(--oops-note-description-color);
|
28
|
-
}
|
29
|
-
`
|
30
|
-
}
|
31
|
-
|
32
|
-
static get properties() {
|
33
|
-
return {
|
34
|
-
icon: String,
|
35
|
-
title: String,
|
36
|
-
description: String
|
37
|
-
}
|
38
|
-
}
|
39
|
-
|
40
|
-
render() {
|
41
|
-
return html`
|
42
|
-
<mwc-icon>${this.icon}</mwc-icon>
|
43
|
-
<div title>${this.title}</div>
|
44
|
-
<div description>${this.description}</div>
|
45
|
-
`
|
46
|
-
}
|
47
|
-
}
|
48
|
-
|
49
|
-
customElements.define('oops-note', OopsNote)
|
@@ -1,81 +0,0 @@
|
|
1
|
-
import gql from 'graphql-tag'
|
2
|
-
import { html, LitElement } from 'lit'
|
3
|
-
|
4
|
-
import { subscribe } from '@operato/graphql'
|
5
|
-
|
6
|
-
export class OopsProgress extends LitElement {
|
7
|
-
static get properties() {
|
8
|
-
return {
|
9
|
-
tag: String,
|
10
|
-
subscription: Boolean
|
11
|
-
}
|
12
|
-
}
|
13
|
-
|
14
|
-
render() {
|
15
|
-
return html` <slot></slot> `
|
16
|
-
}
|
17
|
-
|
18
|
-
disconnectedCallback() {
|
19
|
-
super.disconnectedCallback()
|
20
|
-
this.stopSubscribe()
|
21
|
-
}
|
22
|
-
|
23
|
-
get subscription() {
|
24
|
-
return this._subscription
|
25
|
-
}
|
26
|
-
|
27
|
-
set subscription(subscription) {
|
28
|
-
console.warn('oops-progress#subscription is readonly property')
|
29
|
-
}
|
30
|
-
|
31
|
-
async updated(changes) {
|
32
|
-
if (changes.has('tag') && this.subscription) {
|
33
|
-
await this.stopSubscribe()
|
34
|
-
}
|
35
|
-
}
|
36
|
-
|
37
|
-
async startSubscribe() {
|
38
|
-
if (!this.tag || this._subscription) {
|
39
|
-
return
|
40
|
-
}
|
41
|
-
|
42
|
-
this._subscription = await subscribe(
|
43
|
-
{
|
44
|
-
query: gql`
|
45
|
-
subscription {
|
46
|
-
data(tag: "${this.tag}") {
|
47
|
-
tag
|
48
|
-
data
|
49
|
-
}
|
50
|
-
}`
|
51
|
-
},
|
52
|
-
{
|
53
|
-
next: async ({ data }) => {
|
54
|
-
if (data) {
|
55
|
-
const { progress = 0, message = '' } = data?.data?.data || {}
|
56
|
-
this.dispatchEvent(
|
57
|
-
new CustomEvent('progress', {
|
58
|
-
detail: {
|
59
|
-
progress,
|
60
|
-
message
|
61
|
-
}
|
62
|
-
})
|
63
|
-
)
|
64
|
-
|
65
|
-
if (progress >= 100) {
|
66
|
-
await this.stopSubscribe()
|
67
|
-
this.dispatchEvent(new CustomEvent('finish'))
|
68
|
-
}
|
69
|
-
}
|
70
|
-
}
|
71
|
-
}
|
72
|
-
)
|
73
|
-
}
|
74
|
-
|
75
|
-
async stopSubscribe() {
|
76
|
-
await this._subscription?.unsubscribe()
|
77
|
-
delete this._subscription
|
78
|
-
}
|
79
|
-
}
|
80
|
-
|
81
|
-
customElements.define('oops-progress', OopsProgress)
|
@@ -1,31 +0,0 @@
|
|
1
|
-
import { LitElement, html, css } from 'lit'
|
2
|
-
|
3
|
-
export class OopsSpinner extends LitElement {
|
4
|
-
static get styles() {
|
5
|
-
return css`
|
6
|
-
:host {
|
7
|
-
width: 70px;
|
8
|
-
height: 70px;
|
9
|
-
margin: 0 auto;
|
10
|
-
background: url(/assets/images/spinner.png) 0 0 no-repeat;
|
11
|
-
background-size: 700%;
|
12
|
-
animation: spinner steps(6) 2s infinite both;
|
13
|
-
}
|
14
|
-
|
15
|
-
@keyframes spinner {
|
16
|
-
0% {
|
17
|
-
background-position: 0%;
|
18
|
-
}
|
19
|
-
100% {
|
20
|
-
background-position: 100%;
|
21
|
-
}
|
22
|
-
}
|
23
|
-
`
|
24
|
-
}
|
25
|
-
|
26
|
-
render() {
|
27
|
-
return html``
|
28
|
-
}
|
29
|
-
}
|
30
|
-
|
31
|
-
customElements.define('oops-spinner', OopsSpinner)
|
@@ -1,73 +0,0 @@
|
|
1
|
-
# OOPS Progress 컴포넌트
|
2
|
-
|
3
|
-
긴 시간 진행되는 작업의 진행 상황을 표현해주기 위해 서버에 진행율을 Subscribe하는 클라이언트 컴포넌트이다.
|
4
|
-
이 컴포넌트는 자체적으로 시각적 요소를 포함하지 않지만, 시각적 표현을 위해서 자식 노드(Light DOM)를 포함할 수는 있다.
|
5
|
-
|
6
|
-
## properties
|
7
|
-
|
8
|
-
- tag: String 서브스크립션 태그이며, 서버의 'publishProgress'의 tag와 일치시키도록 한다.
|
9
|
-
- subscription: String (readonly) 이 속성이 값을 가지고 있으면, 서브스크립션 중임을 의미한다.
|
10
|
-
|
11
|
-
## methods
|
12
|
-
|
13
|
-
- startSubscribe() 진행율 구독을 시작한다.
|
14
|
-
- stopSubscribe() 진행율 구독을 종료한다.(서버쪽 작업의 종료를 의미하지 않으며, 클라이언트에서 구독을 종료한다는 의미임.)
|
15
|
-
|
16
|
-
## event
|
17
|
-
|
18
|
-
- progress(event) 서버로부터 진행율이 Subscribe 되었을 때 발생한다.
|
19
|
-
- event.detail : progress 값을 갖는다.
|
20
|
-
- finish(event) 진행율이 100% 도달하면 발생한다.
|
21
|
-
|
22
|
-
## 예시
|
23
|
-
|
24
|
-
### 클라이언트 사이드
|
25
|
-
|
26
|
-
```
|
27
|
-
<oops-progress
|
28
|
-
.tag='progress-pending-job'
|
29
|
-
@progress=${e => {
|
30
|
-
this.progress = e.detail
|
31
|
-
}}
|
32
|
-
@finish=${() => {
|
33
|
-
console.log('complete')
|
34
|
-
}}
|
35
|
-
?hidden=${progress < 0 || progress > 100}
|
36
|
-
>
|
37
|
-
<div>
|
38
|
-
<mwc-linear-progress .progress=${progress / 100}></mwc-linear-progress>
|
39
|
-
<span>Progress : ${progress} % (${message})</span>
|
40
|
-
</div>
|
41
|
-
</oops-progress>
|
42
|
-
|
43
|
-
```
|
44
|
-
|
45
|
-
### 서버사이드
|
46
|
-
|
47
|
-
```
|
48
|
-
import { sleep } from '@things-factory/utils'
|
49
|
-
|
50
|
-
...
|
51
|
-
|
52
|
-
@Mutation(returns => String, { description: 'To reference of pending job progress' })
|
53
|
-
async referencePendingJob(
|
54
|
-
@Root() _,
|
55
|
-
@Ctx() context: any
|
56
|
-
) : Promise<string> {
|
57
|
-
|
58
|
-
const { domain } = context.state
|
59
|
-
|
60
|
-
for(var i = 0;i <= 100;i++) {
|
61
|
-
await sleep(100)
|
62
|
-
|
63
|
-
publishProgress({
|
64
|
-
domain,
|
65
|
-
tag: 'progress-pending-job',
|
66
|
-
progress: i,
|
67
|
-
message: `${i * 10} / 1000`
|
68
|
-
})
|
69
|
-
}
|
70
|
-
|
71
|
-
return 'success'
|
72
|
-
}
|
73
|
-
```
|