diff --git a/.storybook/main.js b/.storybook/main.js index 6009a71..b315022 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -1,3 +1,5 @@ +const path = require('path'); + module.exports = { stories: ['../projects/**/*.stories.ts'], addons: [ @@ -5,5 +7,19 @@ module.exports = { '@storybook/addon-links', '@storybook/addon-notes', '@storybook/addon-knobs' - ] + ], + webpackFinal: async (config) => { + for (const rule of config.module.rules) { + if (-1 < String(rule.test).indexOf('scss')) { + rule.use.push({ + loader: 'sass-resources-loader', + options: { + resources: [path.join(__dirname, 'styles.scss')] + } + }); + } + } + + return config; + } }; diff --git a/.storybook/styles.scss b/.storybook/styles.scss new file mode 100644 index 0000000..3c0c880 --- /dev/null +++ b/.storybook/styles.scss @@ -0,0 +1,10 @@ +:root { + --ucap-screen-max-xs: 575; + --ucap-screen-min-sm: 576; + --ucap-screen-max-sm: 767; + --ucap-screen-min-md: 768; + --ucap-screen-max-md: 991; + --ucap-screen-min-lg: 992; + --ucap-screen-max-lg: 1199; + --ucap-screen-min-xl: 1200; +} diff --git a/angular.json b/angular.json index 8d29d2a..6435907 100644 --- a/angular.json +++ b/angular.json @@ -1436,6 +1436,49 @@ } } }, + "ui-chat": { + "projectType": "library", + "schematics": { + "@schematics/angular:component": { + "style": "scss" + } + }, + "root": "projects/ui-chat", + "sourceRoot": "projects/ui-chat/src", + "prefix": "ucap-chat", + "architect": { + "build": { + "builder": "@angular-devkit/build-ng-packagr:build", + "options": { + "tsConfig": "projects/ui-chat/tsconfig.lib.json", + "project": "projects/ui-chat/ng-package.json" + }, + "configurations": { + "production": { + "tsConfig": "projects/ui-chat/tsconfig.lib.prod.json" + } + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "projects/ui-chat/src/test.ts", + "tsConfig": "projects/ui-chat/tsconfig.spec.json", + "karmaConfig": "projects/ui-chat/karma.conf.js" + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": [ + "projects/ui-chat/tsconfig.lib.json", + "projects/ui-chat/tsconfig.spec.json" + ], + "exclude": ["**/node_modules/**"] + } + } + } + }, "ui-skin-default": { "projectType": "library", "schematics": { diff --git a/package-lock.json b/package-lock.json index e8cee95..435954a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -809,6 +809,197 @@ "integrity": "sha512-NmOazeJ2WVT5eTyNHXYxBRAHic6i6Ku5DgsGWBgjUIR/Qmwb/i/xpagbA9WQQZ2OrGbp4ICEYgGkikeIrlQLPA==", "dev": true }, + "@babel/cli": { + "version": "7.8.4", + "resolved": "https://nexus.loafle.net/repository/npm-all/@babel/cli/-/cli-7.8.4.tgz", + "integrity": "sha512-XXLgAm6LBbaNxaGhMAznXXaxtCWfuv6PIDJ9Alsy9JYTOh+j2jJz+L/162kkfU1j/pTSxK1xGmlwI4pdIMkoag==", + "dev": true, + "requires": { + "chokidar": "^2.1.8", + "commander": "^4.0.1", + "convert-source-map": "^1.1.0", + "fs-readdir-recursive": "^1.1.0", + "glob": "^7.0.0", + "lodash": "^4.17.13", + "make-dir": "^2.1.0", + "slash": "^2.0.0", + "source-map": "^0.5.0" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://nexus.loafle.net/repository/npm-all/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "optional": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://nexus.loafle.net/repository/npm-all/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "optional": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://nexus.loafle.net/repository/npm-all/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true, + "optional": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://nexus.loafle.net/repository/npm-all/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "optional": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + } + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://nexus.loafle.net/repository/npm-all/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "optional": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "commander": { + "version": "4.1.1", + "resolved": "https://nexus.loafle.net/repository/npm-all/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://nexus.loafle.net/repository/npm-all/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "optional": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://nexus.loafle.net/repository/npm-all/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "optional": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + } + }, + "fsevents": { + "version": "1.2.13", + "resolved": "https://nexus.loafle.net/repository/npm-all/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "dev": true, + "optional": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://nexus.loafle.net/repository/npm-all/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "optional": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://nexus.loafle.net/repository/npm-all/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "optional": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://nexus.loafle.net/repository/npm-all/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "optional": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://nexus.loafle.net/repository/npm-all/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "optional": true, + "requires": { + "is-buffer": "^1.1.5" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://nexus.loafle.net/repository/npm-all/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "optional": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "slash": { + "version": "2.0.0", + "resolved": "https://nexus.loafle.net/repository/npm-all/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://nexus.loafle.net/repository/npm-all/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "optional": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, "@babel/code-frame": { "version": "7.8.3", "resolved": "https://nexus.loafle.net/repository/npm-all/@babel/code-frame/-/code-frame-7.8.3.tgz", @@ -3317,43 +3508,48 @@ "dev": true }, "@ucap/ng-store-chat": { - "version": "file:pack/ucap-ng-store-chat-0.0.5.tgz", - "integrity": "sha512-MuEZLs9jnL+eJ5CcHcvBFDuSyPhzWmy4xXBc7MpbCf+gaxZTzZv3NRFnHuB8ECCG/uIW2FE25VwvKCd/gJrY4Q==", + "version": "file:pack/ucap-ng-store-chat-0.0.8.tgz", + "integrity": "sha512-f/Smoy/A97JV2Tsd7IIAeQcNRrthxKT+S01PrVyzjNktDvcxOurnIXGacytU9sfkEMP2rOFCuWKv5p21rvVg6g==", "dev": true }, "@ucap/ng-store-group": { - "version": "file:pack/ucap-ng-store-group-0.0.6.tgz", - "integrity": "sha512-lqTUbHz6xi20yQ1nNeMJRY5/vSuWUbvXd7CawoR5z9pWtEOSUvFUh8bI7OK3X1XACP/V1U+2aBgX8MfR1qRVfg==", + "version": "file:pack/ucap-ng-store-group-0.0.9.tgz", + "integrity": "sha512-KJ4E/kZECAkT6zwA1FiDCrhGevCx9so2Knz08kU49broquZQlOtbV70tPj1fA0XBnaY3hL7uUKXqvAfC7OXj0g==", "dev": true }, "@ucap/ng-store-organization": { - "version": "file:pack/ucap-ng-store-organization-0.0.4.tgz", - "integrity": "sha512-m8WJ2aKZuTYz0JKr2sGAyrP83PK1EIa4vzn2nQCouIfA92kD3jYopy6x3jOgdDaK2vxYcaEJqPiKmTG3fhcLGA==", + "version": "file:pack/ucap-ng-store-organization-0.0.8.tgz", + "integrity": "sha512-vWWyPukVWeUPOxXkdWPN9s36V4EuMVuR8vPfOfKwnh09TxV8Efl19jIYYtNo92L1H/lF0OKfaz5eR9Aw76v+FA==", "dev": true }, "@ucap/ng-ui": { - "version": "file:pack/ucap-ng-ui-0.0.5.tgz", - "integrity": "sha512-wPvFlE665jMppq8oq3oESeaLP2SjdP+mqoJlEpxf4Dc2psNyZ93bR/+/Cj6PwZz0TYIXc8ah6pdYTWI3140hOw==", + "version": "file:pack/ucap-ng-ui-0.0.11.tgz", + "integrity": "sha512-Vrl6LFQyBwju76RALrF0/dH9p+PJ4nX33dy99QSx6RUJHQ80C0qAmO/DFS1Ln0LZaDc4KoYIHTAOLvX4WLHS5w==", "dev": true }, "@ucap/ng-ui-authentication": { - "version": "file:pack/ucap-ng-ui-authentication-0.0.19.tgz", - "integrity": "sha512-bzGQjmGTL8G1Awkz2zqGoqo/ODHh0jzCnBiwrRfJti4/IhCjCPcfG85DU8wRh6WW4Mij6CG0/h6D7SwcjJg9bQ==", + "version": "file:pack/ucap-ng-ui-authentication-0.0.20.tgz", + "integrity": "sha512-1FhqwODVL51NC39mwi/2MECMQiyM+qXAlVp2/BrvN+piXXRz/qp62Iwyf/jww+N8aVCe3dqbktJl/tuPacm4/Q==", + "dev": true + }, + "@ucap/ng-ui-chat": { + "version": "file:pack/ucap-ng-ui-chat-0.0.3.tgz", + "integrity": "sha512-RRw533PNi0vVCxH1QiogOkJEC/dWGsSFtK3hdJ/ZlcPCT7G81FnnXVY3HPIzu1MhxnSb7KfVJLZhx2RFEfEXWA==", "dev": true }, "@ucap/ng-ui-group": { - "version": "file:pack/ucap-ng-ui-group-0.0.27.tgz", - "integrity": "sha512-lVz68N1GHA8Ii+KsKcRp092ji+R/0U6u/5gWUinvO0bvPg0fL91DE556Tk07jHi+j7rgNp3KSsu/Se2RfYV/PA==", + "version": "file:pack/ucap-ng-ui-group-0.0.30.tgz", + "integrity": "sha512-LJXwWZ4anO/ScpI+c6IUfwjmcW9tocQq86/cHi8m6SaQwaMq3jltlN2x8WLzRefd72KysLyJHZrX5L1zMLcXog==", "dev": true }, "@ucap/ng-ui-organization": { - "version": "file:pack/ucap-ng-ui-organization-0.0.12.tgz", - "integrity": "sha512-AEDukfFuW9+s2z0iRiJnuRxCGiaZhAyL8qTtAd0m1r9pZebyAcu4Pub4O3VhmgF1Wook3GJ1CdBpzWAQBoks0w==", + "version": "file:pack/ucap-ng-ui-organization-0.0.27.tgz", + "integrity": "sha512-BC0Jxoxia/+Kho+1oAXE+7+K9iXLhVYVWPVCmmzSRGYGrIZu1skNzzKCNZh6WxYOr7LAJ6ZOp+FgYDfKS7iHMg==", "dev": true }, "@ucap/ng-ui-skin-default": { "version": "file:pack/ucap-ng-ui-skin-default-0.0.1.tgz", - "integrity": "sha512-lX5Idywy0jspDFDFHy9y0Wz048ReIM0/+6melCfDzMOeIb3UVf8U6Ata10ivZzkVHmISQOtukUG1P2IAb1NbYA==" + "integrity": "sha512-kfbbfHZ2b1mQL5SflvM9xn86d53NFEx3yTCaQSx16VSEetbQAtb6Qp1/VedDxK6NcWHp+s/Msw5cfuypN1gwug==" }, "@ucap/ng-web-socket": { "version": "file:pack/ucap-ng-web-socket-0.0.2.tgz", @@ -3467,6 +3663,12 @@ "integrity": "sha512-qxBog4wSit25HEq5a2pBtVE4NPQoqwmTeFuCqZBERc1x6Bw1zoA2aCVQ6yRFCNBguTyH0NQMSBFq6rnXwNrgBg==", "dev": true }, + "@ucap/ui-scss": { + "version": "0.0.3", + "resolved": "https://nexus.loafle.net/repository/npm-all/@ucap/ui-scss/-/ui-scss-0.0.3.tgz", + "integrity": "sha512-E+hrBasMzzm27TuPlLxMCkYin4uMN62kLRmeXi9/qdeX6ty+GkqvfkdzV9lvmyZfNvC0VVFKS0eruLEWW6RDvg==", + "dev": true + }, "@ucap/web-socket": { "version": "0.0.10", "resolved": "https://nexus.loafle.net/repository/npm-all/@ucap/web-socket/-/web-socket-0.0.10.tgz", @@ -4320,6 +4522,20 @@ } } }, + "babel-eslint": { + "version": "10.1.0", + "resolved": "https://nexus.loafle.net/repository/npm-all/babel-eslint/-/babel-eslint-10.1.0.tgz", + "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.7.0", + "@babel/traverse": "^7.7.0", + "@babel/types": "^7.7.0", + "eslint-visitor-keys": "^1.0.0", + "resolve": "^1.12.0" + } + }, "babel-helper-evaluate-path": { "version": "0.5.0", "resolved": "https://nexus.loafle.net/repository/npm-all/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.5.0.tgz", @@ -7842,6 +8058,12 @@ "estraverse": "^4.1.1" } }, + "eslint-visitor-keys": { + "version": "1.1.0", + "resolved": "https://nexus.loafle.net/repository/npm-all/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "dev": true + }, "esprima": { "version": "4.0.1", "resolved": "https://nexus.loafle.net/repository/npm-all/esprima/-/esprima-4.0.1.tgz", @@ -8652,6 +8874,12 @@ "minipass": "^3.0.0" } }, + "fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://nexus.loafle.net/repository/npm-all/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true + }, "fs-write-stream-atomic": { "version": "1.0.10", "resolved": "https://nexus.loafle.net/repository/npm-all/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", @@ -14874,553 +15102,11 @@ } }, "fsevents": { - "version": "1.2.12", - "resolved": "https://nexus.loafle.net/repository/npm-all/fsevents/-/fsevents-1.2.12.tgz", - "integrity": "sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q==", + "version": "1.2.13", + "resolved": "https://nexus.loafle.net/repository/npm-all/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "dev": true, - "optional": true, - "requires": { - "node-pre-gyp": "*" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.4", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "3.2.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "bundled": true, - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.9.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.9.0" - } - }, - "mkdirp": { - "version": "0.5.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.3.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.14.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4.4.2" - } - }, - "nopt": { - "version": "4.0.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npm-normalize-package-bin": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1", - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - } - }, - "readable-stream": { - "version": "2.3.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.7.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.7.1", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.13", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "yallist": { - "version": "3.1.1", - "bundled": true, - "dev": true, - "optional": true - } - } + "optional": true }, "globby": { "version": "8.0.2", @@ -16481,6 +16167,29 @@ } } }, + "sass-resources-loader": { + "version": "2.0.3", + "resolved": "https://nexus.loafle.net/repository/npm-all/sass-resources-loader/-/sass-resources-loader-2.0.3.tgz", + "integrity": "sha512-kYujKXFPZvh5QUT+0DO35P93G6GeIRMP4c941Ilbvey5lo+iICFs2H4hP2CFHl68Llg7h2iXqe0RQpDoUzjUSw==", + "dev": true, + "requires": { + "@babel/cli": "^7.4.4", + "@babel/preset-env": "^7.4.5", + "async": "^3.0.1", + "babel-eslint": "^10.0.2", + "chalk": "^2.4.2", + "glob": "^7.1.1", + "loader-utils": "^1.0.4" + }, + "dependencies": { + "async": { + "version": "3.2.0", + "resolved": "https://nexus.loafle.net/repository/npm-all/async/-/async-3.2.0.tgz", + "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==", + "dev": true + } + } + }, "saucelabs": { "version": "1.5.0", "resolved": "https://nexus.loafle.net/repository/npm-all/saucelabs/-/saucelabs-1.5.0.tgz", @@ -19274,553 +18983,11 @@ } }, "fsevents": { - "version": "1.2.12", - "resolved": "https://nexus.loafle.net/repository/npm-all/fsevents/-/fsevents-1.2.12.tgz", - "integrity": "sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q==", + "version": "1.2.13", + "resolved": "https://nexus.loafle.net/repository/npm-all/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "dev": true, - "optional": true, - "requires": { - "node-pre-gyp": "*" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.4", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "3.2.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "bundled": true, - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.9.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.9.0" - } - }, - "mkdirp": { - "version": "0.5.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.3.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.14.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4.4.2" - } - }, - "nopt": { - "version": "4.0.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npm-normalize-package-bin": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1", - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - } - }, - "readable-stream": { - "version": "2.3.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.7.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.7.1", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.13", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "yallist": { - "version": "3.1.1", - "bundled": true, - "dev": true, - "optional": true - } - } + "optional": true }, "is-binary-path": { "version": "1.0.1", @@ -20216,553 +19383,11 @@ } }, "fsevents": { - "version": "1.2.12", - "resolved": "https://nexus.loafle.net/repository/npm-all/fsevents/-/fsevents-1.2.12.tgz", - "integrity": "sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q==", + "version": "1.2.13", + "resolved": "https://nexus.loafle.net/repository/npm-all/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "dev": true, - "optional": true, - "requires": { - "node-pre-gyp": "*" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.4", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "3.2.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "bundled": true, - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.9.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.9.0" - } - }, - "mkdirp": { - "version": "0.5.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.3.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.14.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4.4.2" - } - }, - "nopt": { - "version": "4.0.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npm-normalize-package-bin": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1", - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - } - }, - "readable-stream": { - "version": "2.3.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.7.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.7.1", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.13", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "yallist": { - "version": "3.1.1", - "bundled": true, - "dev": true, - "optional": true - } - } + "optional": true }, "is-absolute-url": { "version": "3.0.3", diff --git a/package.json b/package.json index 67d7bd0..a042fec 100644 --- a/package.json +++ b/package.json @@ -45,11 +45,12 @@ "build:store-chat": "node ./scripts/build.js store-chat", "build:store-group": "node ./scripts/build.js store-group", "build:store-organization": "node ./scripts/build.js store-organization", - "build:ui:all": "npm-run-all -s build:ui build:ui-organization build:ui-authentication build:ui-group", + "build:ui:all": "npm-run-all -s build:ui build:ui-organization build:ui-authentication build:ui-group build:ui-chat", "build:ui": "node ./scripts/build.js ui", "build:ui-organization": "node ./scripts/build.js ui-organization", "build:ui-authentication": "node ./scripts/build.js ui-authentication", "build:ui-group": "node ./scripts/build.js ui-group", + "build:ui-chat": "node ./scripts/build.js ui-chat", "build:ui-skin:all": "npm-run-all -s build:ui-skin-default", "build:ui-skin-default": "node ./scripts/build.js ui-skin-default useScssBundle", "publish:all": "npm-run-all -s publish:logger publish:core publish:util:all publish:api:all publish:protocol:all publish:native:all publish:store:all publish:ui:all publish:ui-skin:all", @@ -91,11 +92,12 @@ "publish:store-chat": "cd ./dist/store-chat && npm publish", "publish:store-group": "cd ./dist/store-group && npm publish", "publish:store-organization": "cd ./dist/store-organization && npm publish", - "publish:ui:all": "npm-run-all -s publish:ui publish:ui-organization publish:ui-authentication publish:ui-group", + "publish:ui:all": "npm-run-all -s publish:ui publish:ui-organization publish:ui-authentication publish:ui-group publish:ui-chat", "publish:ui": "cd ./dist/ui && npm publish", "publish:ui-organization": "cd ./dist/ui-organization && npm publish", "publish:ui-authentication": "cd ./dist/ui-authentication && npm publish", "publish:ui-group": "cd ./dist/ui-group && npm publish", + "publish:ui-chat": "cd ./dist/ui-chat && npm publish", "publish:ui-skin:all": "npm-run-all -s publish:ui-skin-default", "publish:ui-skin-default": "cd ./dist/ui-skin-default && npm publish", "test": "ng test", @@ -179,13 +181,14 @@ "@ucap/ng-protocol-sync": "file:pack/ucap-ng-protocol-sync-0.0.3.tgz", "@ucap/ng-protocol-umg": "file:pack/ucap-ng-protocol-umg-0.0.3.tgz", "@ucap/ng-store-authentication": "file:pack/ucap-ng-store-authentication-0.0.10.tgz", - "@ucap/ng-store-chat": "file:pack/ucap-ng-store-chat-0.0.5.tgz", - "@ucap/ng-store-group": "file:pack/ucap-ng-store-group-0.0.6.tgz", - "@ucap/ng-store-organization": "file:pack/ucap-ng-store-organization-0.0.4.tgz", - "@ucap/ng-ui": "file:pack/ucap-ng-ui-0.0.5.tgz", - "@ucap/ng-ui-authentication": "file:pack/ucap-ng-ui-authentication-0.0.19.tgz", - "@ucap/ng-ui-group": "file:pack/ucap-ng-ui-group-0.0.27.tgz", - "@ucap/ng-ui-organization": "file:pack/ucap-ng-ui-organization-0.0.12.tgz", + "@ucap/ng-store-chat": "file:pack/ucap-ng-store-chat-0.0.8.tgz", + "@ucap/ng-store-group": "file:pack/ucap-ng-store-group-0.0.9.tgz", + "@ucap/ng-store-organization": "file:pack/ucap-ng-store-organization-0.0.8.tgz", + "@ucap/ng-ui": "file:pack/ucap-ng-ui-0.0.11.tgz", + "@ucap/ng-ui-authentication": "file:pack/ucap-ng-ui-authentication-0.0.20.tgz", + "@ucap/ng-ui-chat": "file:pack/ucap-ng-ui-chat-0.0.3.tgz", + "@ucap/ng-ui-group": "file:pack/ucap-ng-ui-group-0.0.30.tgz", + "@ucap/ng-ui-organization": "file:pack/ucap-ng-ui-organization-0.0.27.tgz", "@ucap/ng-ui-skin-default": "file:pack/ucap-ng-ui-skin-default-0.0.1.tgz", "@ucap/ng-web-socket": "file:pack/ucap-ng-web-socket-0.0.2.tgz", "@ucap/ng-web-storage": "file:pack/ucap-ng-web-storage-0.0.3.tgz", @@ -206,6 +209,7 @@ "@ucap/protocol-status": "~0.0.5", "@ucap/protocol-sync": "~0.0.4", "@ucap/protocol-umg": "~0.0.5", + "@ucap/ui-scss": "~0.0.3", "@ucap/web-socket": "~0.0.5", "@ucap/web-storage": "~0.0.5", "autolinker": "^3.13.0", @@ -236,6 +240,7 @@ "queueing-subject": "^0.3.4", "rimraf": "^3.0.2", "rxjs": "~6.5.4", + "sass-resources-loader": "^2.0.3", "scss-bundle": "^3.1.1", "ts-node": "~8.3.0", "tslib": "^1.11.1", diff --git a/projects/store-chat/package.json b/projects/store-chat/package.json index b911542..4830cda 100644 --- a/projects/store-chat/package.json +++ b/projects/store-chat/package.json @@ -1,6 +1,6 @@ { "name": "@ucap/ng-store-chat", - "version": "0.0.5", + "version": "0.0.8", "publishConfig": { "registry": "https://nexus.loafle.net/repository/npm-ucap/" }, diff --git a/projects/store-chat/src/lib/store/room/actions.ts b/projects/store-chat/src/lib/store/room/actions.ts index b15f6c7..56780c6 100644 --- a/projects/store-chat/src/lib/store/room/actions.ts +++ b/projects/store-chat/src/lib/store/room/actions.ts @@ -13,6 +13,8 @@ import { Open3Response as CreateTimerResponse, ExitRequest as DeleteRequest, ExitResponse as DeleteResponse, + ExitAllRequest as DeleteMultiRequest, + ExitAllResponse as DeleteMultiResponse, UpdateRequest, UpdateResponse, InviteRequest, @@ -20,7 +22,8 @@ import { ExitForcingRequest, ExitForcingResponse, UpdateTimerSetRequest, - UpdateTimerSetResponse + UpdateTimerSetResponse, + UserInfoShort } from '@ucap/protocol-room'; /** @@ -32,6 +35,7 @@ export const rooms = createAction( ); /** * Success of rooms request + * RoomUserData is detail type. */ export const roomsSuccess = createAction( '[ucap::chat::room] rooms Success', @@ -51,6 +55,31 @@ export const roomsFailure = createAction( props<{ error: any }>() ); +/** + * Success of rooms2 request + * RoomUserData is detail, short type both. + */ +export const rooms2Success = createAction( + '[ucap::chat::room] rooms2 Success', + props<{ + roomList: RoomInfo[]; + roomUserInfoMap: { + [param: string]: { + userInfoShortList: UserInfoShort[]; + userInfoList: RoomUserInfo[]; + }; + }; + syncDate: string; + }>() +); +/** + * Failure of rooms2 request + */ +export const rooms2Failure = createAction( + '[ucap::chat::room] rooms2 Failure', + props<{ error: any }>() +); + /** * retrieve room information and list of user information */ @@ -142,6 +171,28 @@ export const delFailure = createAction( props<{ error: any }>() ); +/** + * exit from multi room + */ +export const delMulti = createAction( + '[ucap::chat::room] delMulti', + props<{ req: DeleteMultiRequest }>() +); +/** + * Success of delMulti request + */ +export const delMultiSuccess = createAction( + '[ucap::chat::room] delMulti Success', + props<{ res: DeleteMultiResponse }>() +); +/** + * Failure of delMulti request + */ +export const delMultiFailure = createAction( + '[ucap::chat::room] delMulti Failure', + props<{ error: any }>() +); + /** * update room information */ diff --git a/projects/store-chat/src/lib/store/room/effects.ts b/projects/store-chat/src/lib/store/room/effects.ts index b907c5f..ae3ded9 100644 --- a/projects/store-chat/src/lib/store/room/effects.ts +++ b/projects/store-chat/src/lib/store/room/effects.ts @@ -17,6 +17,7 @@ import { OpenResponse as CreateResponse, Open3Response as CreateTimerResponse, ExitResponse as DeleteResponse, + ExitAllResponse as DeleteMultiResponse, UpdateResponse, InviteResponse, ExitForcingResponse, @@ -67,7 +68,12 @@ import { expelFailure, updateTimeRoomInterval, updateTimeRoomIntervalSuccess, - updateTimeRoomIntervalFailure + updateTimeRoomIntervalFailure, + rooms2Success, + rooms2Failure, + delMulti, + delMultiSuccess, + delMultiFailure } from './actions'; @Injectable() @@ -75,7 +81,7 @@ export class Effects { sessionCreatedForRooms$ = createEffect(() => { return this.actions$.pipe( ofType(LoginActions.sessionCreated), - map(action => rooms({ localeCode: action.loginSession.localeCode })) + map((action) => rooms({ localeCode: action.loginSession.localeCode })) ); }); @@ -84,17 +90,32 @@ export class Effects { ofType(rooms), withLatestFrom(this.store.pipe(select(RoomSelector.roomsSyncDate))), switchMap(([action, syncDate]) => { + // // CASE :: RoomUser Data 중 Detail data 만 수집. + // return this.syncProtocolService + // .room({ syncDate, localeCode: action.localeCode }) + // .pipe( + // map((res) => { + // return roomsSuccess({ + // roomList: res.roomList, + // roomUserInfoMap: res.roomUserInfoMap, + // syncDate: res.res.syncDate + // }); + // }), + // catchError((error) => of(roomsFailure({ error }))) + // ); + + // CASE :: RoomUser Data 중 Detail data, Short data 수집. return this.syncProtocolService - .room({ syncDate, localeCode: action.localeCode }) + .room2({ syncDate, localeCode: action.localeCode }) .pipe( - map(res => - roomsSuccess({ + map((res) => { + return rooms2Success({ roomList: res.roomList, roomUserInfoMap: res.roomUserInfoMap, syncDate: res.res.syncDate - }) - ), - catchError(error => of(roomsFailure({ error }))) + }); + }), + catchError((error) => of(rooms2Failure({ error }))) ); }) ); @@ -103,16 +124,16 @@ export class Effects { room$ = createEffect(() => { return this.actions$.pipe( ofType(room), - map(action => action.req), - switchMap(req => { + map((action) => action.req), + switchMap((req) => { return this.roomProtocolService.info(req).pipe( - map(res => + map((res) => roomSuccess({ roomInfo: res.roomInfo, userInfoList: res.userInfoList }) ), - catchError(error => of(roomFailure({ error }))) + catchError((error) => of(roomFailure({ error }))) ); }) ); @@ -121,13 +142,13 @@ export class Effects { create$ = createEffect(() => this.actions$.pipe( ofType(create), - map(action => action.req), - exhaustMap(req => { + map((action) => action.req), + exhaustMap((req) => { return this.roomProtocolService.open(req).pipe( map((res: CreateResponse) => { return createSuccess({ res }); }), - catchError(error => of(createFailure({ error }))) + catchError((error) => of(createFailure({ error }))) ); }) ) @@ -136,13 +157,13 @@ export class Effects { createTimer$ = createEffect(() => this.actions$.pipe( ofType(createTimer), - map(action => action.req), - exhaustMap(req => { + map((action) => action.req), + exhaustMap((req) => { return this.roomProtocolService.open3(req).pipe( map((res: CreateTimerResponse) => { return createTimerSuccess({ res }); }), - catchError(error => of(createTimerFailure({ error }))) + catchError((error) => of(createTimerFailure({ error }))) ); }) ) @@ -151,14 +172,30 @@ export class Effects { del$ = createEffect(() => this.actions$.pipe( ofType(del), - map(action => action.req), - exhaustMap(req => { + map((action) => action.req), + exhaustMap((req) => { return this.roomProtocolService.exit(req).pipe( switchMap((res: DeleteResponse) => [ close({ roomIds: [res.roomId] }), delSuccess({ res }) ]), - catchError(error => of(delFailure({ error }))) + catchError((error) => of(delFailure({ error }))) + ); + }) + ) + ); + + delMulti$ = createEffect(() => + this.actions$.pipe( + ofType(delMulti), + map((action) => action.req), + exhaustMap((req) => { + return this.roomProtocolService.exitAll(req).pipe( + switchMap((res: DeleteMultiResponse) => [ + close({ roomIds: res.roomIds }), + delMultiSuccess({ res }) + ]), + catchError((error) => of(delMultiFailure({ error }))) ); }) ) @@ -167,13 +204,13 @@ export class Effects { update$ = createEffect(() => this.actions$.pipe( ofType(update), - map(action => action.req), - exhaustMap(req => { + map((action) => action.req), + exhaustMap((req) => { return this.roomProtocolService.update(req).pipe( map((res: UpdateResponse) => { return updateSuccess({ res }); }), - catchError(error => of(updateFailure({ error }))) + catchError((error) => of(updateFailure({ error }))) ); }) ) @@ -182,7 +219,7 @@ export class Effects { excludeUser$ = createEffect(() => { return this.actions$.pipe( ofType(excludeUser), - map(action => + map((action) => excludeUserSuccess({ roomId: action.roomId, userSeqs: action.userSeqs @@ -194,21 +231,21 @@ export class Effects { open$ = createEffect(() => { return this.actions$.pipe( ofType(open), - map(action => openSuccess({ roomIds: [...action.roomIds] })) + map((action) => openSuccess({ roomIds: [...action.roomIds] })) ); }); close$ = createEffect(() => { return this.actions$.pipe( ofType(close), - map(action => closeSuccess({ roomIds: [...action.roomIds] })) + map((action) => closeSuccess({ roomIds: [...action.roomIds] })) ); }); inviteOrCreate$ = createEffect(() => this.actions$.pipe( ofType(inviteOrCreate), - map(action => { + map((action) => { const roomInfo = action.roomInfo; const localeCode = action.localeCode; @@ -235,7 +272,7 @@ export class Effects { invite$ = createEffect(() => this.actions$.pipe( ofType(invite), - exhaustMap(action => { + exhaustMap((action) => { const req = action.req; const localeCode = action.localeCode; @@ -252,7 +289,7 @@ export class Effects { }) ]; }), - catchError(error => of(inviteFailure({ error }))) + catchError((error) => of(inviteFailure({ error }))) ); }) ) @@ -261,13 +298,13 @@ export class Effects { expel$ = createEffect(() => this.actions$.pipe( ofType(expel), - map(action => action.req), - exhaustMap(req => { + map((action) => action.req), + exhaustMap((req) => { return this.roomProtocolService.exitForcing(req).pipe( map((res: ExitForcingResponse) => { return expelSuccess({ res }); }), - catchError(error => of(expelFailure({ error }))) + catchError((error) => of(expelFailure({ error }))) ); }) ) @@ -276,13 +313,13 @@ export class Effects { updateTimeRoomInterval$ = createEffect(() => this.actions$.pipe( ofType(updateTimeRoomInterval), - map(action => action.req), - exhaustMap(req => { + map((action) => action.req), + exhaustMap((req) => { return this.roomProtocolService.updateTimerSet(req).pipe( map((res: UpdateTimerSetResponse) => { return updateTimeRoomIntervalSuccess({ res }); }), - catchError(error => of(updateTimeRoomIntervalFailure({ error }))) + catchError((error) => of(updateTimeRoomIntervalFailure({ error }))) ); }) ) @@ -291,7 +328,7 @@ export class Effects { inviteNotification$ = createEffect(() => { return this.actions$.pipe( ofType(inviteNotification), - map(action => + map((action) => room({ req: { roomId: action.noti.roomId, @@ -306,7 +343,7 @@ export class Effects { exitNotification$ = createEffect(() => { return this.actions$.pipe( ofType(exitNotification), - switchMap(action => { + switchMap((action) => { if (action.userSeq === action.senderSeq) { return [ close({ roomIds: [action.roomId] }), diff --git a/projects/store-chat/src/lib/store/room/reducers.ts b/projects/store-chat/src/lib/store/room/reducers.ts index 62500b7..7a2b2b2 100644 --- a/projects/store-chat/src/lib/store/room/reducers.ts +++ b/projects/store-chat/src/lib/store/room/reducers.ts @@ -1,6 +1,10 @@ import { createReducer, on } from '@ngrx/store'; -import { UserInfo as RoomUserInfo } from '@ucap/protocol-room'; +import { + UserInfo as RoomUserInfo, + UserInfoShort as RoomUserInfoShort, + RoomInfo +} from '@ucap/protocol-room'; import * as chattingActions from '../chatting/actions'; @@ -8,14 +12,19 @@ import { initialState, adapterRoom, adapterRoomUser, - RoomUserMap + RoomUserMap, + RoomUserShortMap, + adapterRoomUserShort } from './state'; import { roomsSuccess, roomSuccess, excludeUser, excludeUserSuccess, - delSuccess + delSuccess, + rooms2Success, + delMultiSuccess, + updateSuccess } from './actions'; export const reducer = createReducer( @@ -40,7 +49,7 @@ export const reducer = createReducer( const value = state.rooms.entities[key]; unreadTotal += isNaN(value.noReadCnt) ? 0 : value.noReadCnt; } - action.roomList.map(item => (unreadTotal += item.noReadCnt)); + action.roomList.map((item) => (unreadTotal += item.noReadCnt)); return { ...state, @@ -55,6 +64,53 @@ export const reducer = createReducer( }; }), + on(rooms2Success, (state, action) => { + const roomUserMapList: RoomUserMap[] = []; + const roomUserShortMapList: RoomUserShortMap[] = []; + + for (const key in action.roomUserInfoMap) { + if (action.roomUserInfoMap.hasOwnProperty(key)) { + const userInfosMap = action.roomUserInfoMap[key]; + if (!!userInfosMap && 0 < userInfosMap.userInfoList.length) { + roomUserMapList.push({ + roomId: key, + userInfos: userInfosMap.userInfoList + }); + } + if (!!userInfosMap && 0 < userInfosMap.userInfoShortList.length) { + roomUserShortMapList.push({ + roomId: key, + userInfos: userInfosMap.userInfoShortList + }); + } + } + } + + let unreadTotal = 0; + + // tslint:disable-next-line: forin + for (const key in state.rooms.entities) { + const value = state.rooms.entities[key]; + unreadTotal += isNaN(value.noReadCnt) ? 0 : value.noReadCnt; + } + action.roomList.map((item) => (unreadTotal += item.noReadCnt)); + + return { + ...state, + rooms: adapterRoom.upsertMany(action.roomList, { + ...state.rooms, + syncDate: action.syncDate + }), + roomUsers: adapterRoomUser.upsertMany(roomUserMapList, { + ...state.roomUsers + }), + roomUsersShort: adapterRoomUserShort.upsertMany(roomUserShortMapList, { + ...state.roomUsersShort + }), + unreadTotal + }; + }), + on(roomSuccess, (state, action) => { const roomUserMapList: RoomUserMap[] = []; @@ -82,17 +138,27 @@ export const reducer = createReducer( on(excludeUserSuccess, (state, action) => { const roomId = action.roomId; const roomUserMap = state.roomUsers.entities[roomId]; + const roomUserMapShort = state.roomUsersShort.entities[roomId]; const userInfos: RoomUserInfo[] = [...roomUserMap.userInfos]; + const userInfosShort: RoomUserInfoShort[] = [...roomUserMapShort.userInfos]; - action.userSeqs.forEach(userSeq => { + action.userSeqs.forEach((userSeq) => { const userInfo: RoomUserInfo = userInfos.find( - u => userSeq === String(u.seq) + (u) => userSeq === String(u.seq) ); if (!!userInfo && !!userInfo.seq) { userInfo.isJoinRoom = false; } + + const userInfoShort: RoomUserInfoShort = userInfosShort.find( + (u) => userSeq === String(u.seq) + ); + + if (!!userInfoShort && !!userInfoShort.seq) { + userInfoShort.isJoinRoom = false; + } }); return { @@ -108,10 +174,35 @@ export const reducer = createReducer( { ...state.roomUsers } + ), + roomUsersShort: adapterRoomUserShort.updateOne( + { + id: roomId, + changes: { + roomId, + userInfos: userInfosShort + } + }, + { + ...state.roomUsersShort + } ) }; }), + on(updateSuccess, (state, action) => { + const roomInfo = { + ...state.rooms.entities[action.res.roomId], + roomName: action.res.roomName, + receiveAlarm: action.res.receiveAlarm + } as RoomInfo; + + return { + ...state, + rooms: adapterRoom.upsertOne(roomInfo, { ...state.rooms }) + }; + }), + on(delSuccess, (state, action) => { const roomId = action.res.roomId; const room = state.rooms.entities[roomId]; @@ -123,7 +214,27 @@ export const reducer = createReducer( return { ...state, rooms: adapterRoom.removeOne(roomId, { ...state.rooms }), - roomUsers: adapterRoomUser.removeOne(roomId, { ...state.roomUsers }) + roomUsers: adapterRoomUser.removeOne(roomId, { ...state.roomUsers }), + roomUsersShort: adapterRoomUserShort.removeOne(roomId, { + ...state.roomUsersShort + }) + }; + }), + + on(delMultiSuccess, (state, action) => { + const roomIds: string[] = action.res.roomIds; + + if (!roomIds || roomIds.length === 0) { + return state; + } + + return { + ...state, + rooms: adapterRoom.removeMany(roomIds, { ...state.rooms }), + roomUsers: adapterRoomUser.removeMany(roomIds, { ...state.roomUsers }), + roomUsersShort: adapterRoomUserShort.removeMany(roomIds, { + ...state.roomUsersShort + }) }; }) ); diff --git a/projects/store-chat/src/lib/store/room/state.ts b/projects/store-chat/src/lib/store/room/state.ts index 41afa05..c45ee79 100644 --- a/projects/store-chat/src/lib/store/room/state.ts +++ b/projects/store-chat/src/lib/store/room/state.ts @@ -3,22 +3,22 @@ import moment from 'moment'; import { Selector, createSelector } from '@ngrx/store'; import { EntityState, createEntityAdapter, Dictionary } from '@ngrx/entity'; -import { RoomUserDetailData } from '@ucap/protocol-sync'; -import { RoomInfo, UserInfo as RoomUserInfo } from '@ucap/protocol-room'; +import { RoomUserDetailData, RoomUserData } from '@ucap/protocol-sync'; +import { + RoomInfo, + UserInfo as RoomUserInfo, + UserInfoShort as RoomUserInfoShort +} from '@ucap/protocol-room'; export interface RoomState extends EntityState { syncDate: string; } export const adapterRoom = createEntityAdapter({ - selectId: roomInfo => roomInfo.roomId, + selectId: (roomInfo) => roomInfo.roomId, sortComparer: (a, b) => { return ( - moment(b.finalEventDate) - .toDate() - .getTime() - - moment(a.finalEventDate) - .toDate() - .getTime() + moment(b.finalEventDate).toDate().getTime() - + moment(a.finalEventDate).toDate().getTime() ); } }); @@ -28,24 +28,39 @@ export interface RoomUserMap { userInfos: RoomUserInfo[]; } +export interface RoomUserShortMap { + roomId: string; + userInfos: RoomUserInfoShort[]; +} + export interface RoomUserState extends EntityState {} export const adapterRoomUser = createEntityAdapter({ - selectId: roomUserDetailData => roomUserDetailData.roomId + selectId: (roomUserDetailData) => roomUserDetailData.roomId +}); + +export interface RoomUserShortState extends EntityState {} +export const adapterRoomUserShort = createEntityAdapter({ + selectId: (roomUserShortData) => roomUserShortData.roomId }); export interface State { rooms: RoomState; roomUsers: RoomUserState; + roomUsersShort: RoomUserShortState; } const roomInitialState: RoomState = adapterRoom.getInitialState({ syncDate: '' }); const roomUserInitialState: RoomUserState = adapterRoomUser.getInitialState({}); +const roomUserShortInitialState: RoomUserShortState = adapterRoomUserShort.getInitialState( + {} +); export const initialState: State = { rooms: roomInitialState, - roomUsers: roomUserInitialState + roomUsers: roomUserInitialState, + roomUsersShort: roomUserShortInitialState }; const { @@ -62,6 +77,13 @@ const { selectTotal: selectTotalForRoomUser } = adapterRoomUser.getSelectors(); +const { + selectAll: selectAllForRoomUserShort, + selectEntities: selectEntitiesForRoomUserShort, + selectIds: selectIdsForRoomUserShort, + selectTotal: selectTotalForRoomUserShort +} = adapterRoomUserShort.getSelectors(); + export function selectors(selector: Selector) { const selectRooms = createSelector(selector, (state: State) => state.rooms); @@ -70,6 +92,11 @@ export function selectors(selector: Selector) { (state: State) => state.roomUsers ); + const selectRoomUsersShort = createSelector( + selector, + (state: State) => state.roomUsersShort + ); + return { rooms: createSelector(selectRooms, selectAllForRoom), room: createSelector( @@ -78,7 +105,10 @@ export function selectors(selector: Selector) { (roomState: RoomState, entities: Dictionary, roomId: string) => entities && entities[roomId] ), - roomsSyncDate: createSelector(selectRooms, roomState => roomState.syncDate), + roomsSyncDate: createSelector( + selectRooms, + (roomState) => roomState.syncDate + ), roomUsers: createSelector(selectRoomUsers, selectAllForRoomUser), roomUser: createSelector( selectRoomUsers, @@ -89,6 +119,19 @@ export function selectors(selector: Selector) { roomId: string ) => entities && entities[roomId] ), + roomUsersShort: createSelector( + selectRoomUsersShort, + selectAllForRoomUserShort + ), + roomUserShort: createSelector( + selectRoomUsersShort, + selectEntitiesForRoomUserShort, + ( + roomUserShortState: RoomUserShortState, + entities: Dictionary, + roomId: string + ) => entities && entities[roomId] + ), unreadTotal: createSelector( selectRooms, selectAllForRoom, diff --git a/projects/store-group/package.json b/projects/store-group/package.json index fcb026a..f7e089f 100644 --- a/projects/store-group/package.json +++ b/projects/store-group/package.json @@ -1,6 +1,6 @@ { "name": "@ucap/ng-store-group", - "version": "0.0.6", + "version": "0.0.9", "publishConfig": { "registry": "https://nexus.loafle.net/repository/npm-ucap/" }, diff --git a/projects/store-group/src/lib/store/buddy/effects.ts b/projects/store-group/src/lib/store/buddy/effects.ts index af15262..132382f 100644 --- a/projects/store-group/src/lib/store/buddy/effects.ts +++ b/projects/store-group/src/lib/store/buddy/effects.ts @@ -23,7 +23,10 @@ import { SyncProtocolService } from '@ucap/ng-protocol-sync'; import { BuddyProtocolService } from '@ucap/ng-protocol-buddy'; -import { DepartmentSelector } from '@ucap/ng-store-organization'; +import { + DepartmentSelector, + PresenceActions +} from '@ucap/ng-store-organization'; import { LoginActions } from '@ucap/ng-store-authentication'; import * as groupActions from '../group/actions'; @@ -53,7 +56,7 @@ export class Effects { sessionCreatedForBuddy2$ = createEffect(() => { return this.actions$.pipe( ofType(LoginActions.sessionCreated), - map(action => buddy2()) + map((action) => buddy2()) ); }); @@ -63,13 +66,21 @@ export class Effects { withLatestFrom(this.store.pipe(select(BuddySelector.buddySyncDate))), switchMap(([action, syncDate]) => { return this.syncProtocolService.buddy2({ syncDate }).pipe( - map(res => - buddy2Success({ + map((res) => { + // Buddy Presence + this.store.dispatch( + PresenceActions.bulkInfo({ + divCd: 'buddyBulk', + userSeqs: res.buddyInfos.map((userInfo) => userInfo.seq + '') + }) + ); + + return buddy2Success({ buddyList: res.buddyInfos, syncDate: res.res.syncDate - }) - ), - catchError(error => of(buddy2Failure({ error }))) + }); + }), + catchError((error) => of(buddy2Failure({ error }))) ); }) ); @@ -78,13 +89,13 @@ export class Effects { add$ = createEffect(() => this.actions$.pipe( ofType(add), - map(action => action.req), - exhaustMap(req => + map((action) => action.req), + exhaustMap((req) => this.buddyProtocolService.add(req).pipe( map((res: BuddyAddResponse) => { return buddy2(); }), - catchError(error => of(addFailure({ error }))) + catchError((error) => of(addFailure({ error }))) ) ) ) @@ -93,13 +104,13 @@ export class Effects { del$ = createEffect(() => this.actions$.pipe( ofType(del), - map(action => action.req), - exhaustMap(req => + map((action) => action.req), + exhaustMap((req) => this.buddyProtocolService.del(req).pipe( map((res: BuddyDelResponse) => { return delSuccess({ res }); }), - catchError(error => of(delFailure({ error }))) + catchError((error) => of(delFailure({ error }))) ) ) ) @@ -122,7 +133,7 @@ export class Effects { this.moduleConfig.useMyDeptGroup && !!this.moduleConfig.fixedGroupSeqs && this.moduleConfig.fixedGroupSeqs.filter( - fixedGroupSeq => fixedGroupSeq === group.seq + (fixedGroupSeq) => fixedGroupSeq === group.seq ).length > 0 ) { // skip;; @@ -134,7 +145,7 @@ export class Effects { groupSeq: group.seq, groupName: group.name, userSeqs: group.userSeqs.filter( - userSeq => userSeq !== String(req.seq) + (userSeq) => userSeq !== String(req.seq) ) } }) @@ -147,8 +158,9 @@ export class Effects { if ( !!this.moduleConfig.useMyDeptGroup && this.moduleConfig.useMyDeptGroup && - myDeptUserList.filter(deptUser => deptUser.seq === String(req.seq)) - .length > 0 + myDeptUserList.filter( + (deptUser) => deptUser.seq === String(req.seq) + ).length > 0 ) { // skip;; } else { @@ -174,13 +186,13 @@ export class Effects { update$ = createEffect(() => this.actions$.pipe( ofType(update), - map(action => action.req), - exhaustMap(req => + map((action) => action.req), + exhaustMap((req) => this.buddyProtocolService.update(req).pipe( map((res: BuddyUpdateResponse) => { return updateSuccess({ res }); }), - catchError(error => of(updateFailure({ error }))) + catchError((error) => of(updateFailure({ error }))) ) ) ) @@ -196,13 +208,15 @@ export class Effects { if (!!targetUserSeqs && 0 < targetUserSeqs.length) { const addBuddyList: string[] = []; - targetUserSeqs.forEach(userSeq => { + targetUserSeqs.forEach((userSeq) => { if (!buddyList) { addBuddyList.push(userSeq); return; } - const index = buddyList.findIndex(b => String(b.seq) === userSeq); + const index = buddyList.findIndex( + (b) => String(b.seq) === userSeq + ); if (-1 < index) { addBuddyList.push(userSeq); return; @@ -230,13 +244,15 @@ export class Effects { if (!!targetUserSeqs && 0 < targetUserSeqs.length) { const addBuddyList: string[] = []; - targetUserSeqs.forEach(userSeq => { + targetUserSeqs.forEach((userSeq) => { if (!buddyList) { addBuddyList.push(userSeq); return; } - const index = buddyList.findIndex(b => String(b.seq) === userSeq); + const index = buddyList.findIndex( + (b) => String(b.seq) === userSeq + ); if (-1 < index) { addBuddyList.push(userSeq); return; @@ -249,7 +265,7 @@ export class Effects { } if (!!userSeqsForDelete && 0 < userSeqsForDelete.length) { - userSeqsForDelete.forEach(userSeq => { + userSeqsForDelete.forEach((userSeq) => { this.store.dispatch( update({ req: { seq: Number(userSeq), isFavorit: false } }) ); diff --git a/projects/store-group/src/lib/store/group/effects.ts b/projects/store-group/src/lib/store/group/effects.ts index 194696f..880e526 100644 --- a/projects/store-group/src/lib/store/group/effects.ts +++ b/projects/store-group/src/lib/store/group/effects.ts @@ -31,7 +31,7 @@ import { _MODULE_CONFIG } from '../../config/token'; import * as buddyActions from '../buddy/actions'; -import { GroupSelector } from '../state'; +import { GroupSelector, BuddySelector } from '../state'; import { groups, @@ -57,7 +57,7 @@ export class Effects { sessionCreatedForGroups$ = createEffect(() => { return this.actions$.pipe( ofType(LoginActions.sessionCreated), - map(action => groups()) + map((action) => groups()) ); }); @@ -67,13 +67,13 @@ export class Effects { withLatestFrom(this.store.pipe(select(GroupSelector.groupSyncDate))), switchMap(([action, syncDate]) => { return this.syncProtocolService.group2({ syncDate }).pipe( - map(res => + map((res) => groupsSuccess({ groupList: res.groupInfos, syncDate: res.res.syncDate }) ), - catchError(error => of(groupsFailure({ error }))) + catchError((error) => of(groupsFailure({ error }))) ); }) ); @@ -82,7 +82,8 @@ export class Effects { create$ = createEffect(() => this.actions$.pipe( ofType(create), - exhaustMap(action => { + withLatestFrom(this.store.pipe(select(BuddySelector.buddies))), + exhaustMap(([action, buddies]) => { return this.groupProtocolService .add({ groupName: action.groupName @@ -92,6 +93,19 @@ export class Effects { const actions: any[] = []; if (!!action.targetUserSeqs && 0 < action.targetUserSeqs.length) { + const addBuddies: number[] = []; + action.targetUserSeqs.forEach((item) => { + if (!buddies[item]) { + addBuddies.push(Number(item)); + } + }); + if (addBuddies.length > 0) { + actions.push( + buddyActions.add({ + req: { userSeqs: action.targetUserSeqs } + }) + ); + } actions.push( update({ req: { @@ -108,7 +122,7 @@ export class Effects { return actions; }), - catchError(error => of(createFailure({ error }))) + catchError((error) => of(createFailure({ error }))) ); }) ) @@ -128,7 +142,7 @@ export class Effects { // Del Buddy let userSeqsForDelete: string[] = targetGroup.userSeqs.filter( - v => targetUserSeqs.indexOf(v) < 0 + (v) => targetUserSeqs.indexOf(v) < 0 ); // 소속부서(내부서) 고정그룹 사용시 소속부서원을 삭제하지 않는다. @@ -137,18 +151,18 @@ export class Effects { this.moduleConfig.useMyDeptGroup ) { userSeqsForDelete = userSeqsForDelete.filter( - delbuddy => - myDeptUserList.filter(deptUser => deptUser.seq === delbuddy) + (delbuddy) => + myDeptUserList.filter((deptUser) => deptUser.seq === delbuddy) .length === 0 ); } - userSeqsForDelete = userSeqsForDelete.filter(delbuddy => { + userSeqsForDelete = userSeqsForDelete.filter((delbuddy) => { let exist = false; for (const group of groupList) { if ( group.seq !== targetGroup.seq && - group.userSeqs.filter(v => v === delbuddy).length > 0 + group.userSeqs.filter((v) => v === delbuddy).length > 0 ) { exist = true; break; @@ -184,10 +198,10 @@ export class Effects { withLatestFrom(this.store.pipe(select(GroupSelector.groups))), exhaustMap(([action, groupList]) => { // copy to - const toGroup = groupList.find(g => g.seq === action.toGroup.seq); + const toGroup = groupList.find((g) => g.seq === action.toGroup.seq); let toTrgtUserSeqs = toGroup.userSeqs; - action.targetUserSeq.forEach(trgtSeq => { + action.targetUserSeq.forEach((trgtSeq) => { if (toTrgtUserSeqs.indexOf(trgtSeq) > -1) { // ignore } else { @@ -205,7 +219,7 @@ export class Effects { exhaustMap((resTo: GroupUpdateResponse) => { // del from const fromGroup = groupList.find( - g => g.seq === action.fromGroup.seq + (g) => g.seq === action.fromGroup.seq ); const fromTrgtUserSeqs = fromGroup.userSeqs; @@ -215,17 +229,17 @@ export class Effects { groupSeq: action.fromGroup.seq, groupName: action.fromGroup.name, userSeqs: fromTrgtUserSeqs.filter( - trgtSeq => action.targetUserSeq.indexOf(trgtSeq) < 0 + (trgtSeq) => action.targetUserSeq.indexOf(trgtSeq) < 0 ) }) .pipe( map((resFrom: GroupUpdateResponse) => { return groups(); }), - catchError(error => of(moveFromFailure({ error }))) + catchError((error) => of(moveFromFailure({ error }))) ); }), - catchError(error => of(moveToFailure({ error }))) + catchError((error) => of(moveToFailure({ error }))) ); }) ) @@ -246,21 +260,23 @@ export class Effects { // 소속부서(내부서) 고정그룹 사용시 소속부서원을 삭제하지 않는다. if ( !!this.moduleConfig.useMyDeptGroup && - this.moduleConfig.useMyDeptGroup + this.moduleConfig.useMyDeptGroup && + !!myDeptUserList && + myDeptUserList.length > 0 ) { userSeqsForDelete = targetUserSeqs.filter( - delbuddy => - myDeptUserList.filter(deptUser => deptUser.seq === delbuddy) + (delbuddy) => + myDeptUserList.filter((deptUser) => deptUser.seq === delbuddy) .length === 0 ); } - userSeqsForDelete = targetUserSeqs.filter(delbuddy => { + userSeqsForDelete = targetUserSeqs.filter((delbuddy) => { let exist = false; for (const group of groupList) { if ( group.seq !== action.group.seq && - group.userSeqs.filter(v => v === delbuddy).length > 0 + group.userSeqs.filter((v) => v === delbuddy).length > 0 ) { exist = true; break; @@ -271,7 +287,7 @@ export class Effects { if (userSeqsForDelete.length > 0) { // 즐겨찾기 해제. - userSeqsForDelete.forEach(buddySeq => { + userSeqsForDelete.forEach((buddySeq) => { this.store.dispatch( buddyActions.update({ req: { @@ -296,7 +312,7 @@ export class Effects { map((res: GroupDelResponse) => { return delSuccess({ res }); }), - catchError(error => of(delFailure({ error }))) + catchError((error) => of(delFailure({ error }))) ); }) ) @@ -305,13 +321,13 @@ export class Effects { update$ = createEffect(() => this.actions$.pipe( ofType(update), - map(action => action.req), - concatMap(req => + map((action) => action.req), + concatMap((req) => this.groupProtocolService.update2(req).pipe( map((res: GroupUpdateResponse) => { return groups(); }), - catchError(error => of(updateFailure({ error }))) + catchError((error) => of(updateFailure({ error }))) ) ) ) diff --git a/projects/store-organization/ng-package.json b/projects/store-organization/ng-package.json index 0f1144d..d50ff9f 100644 --- a/projects/store-organization/ng-package.json +++ b/projects/store-organization/ng-package.json @@ -6,9 +6,13 @@ "umdModuleIds": { "@ngrx/store": "@ngrx/store", "@ngrx/effects": "@ngrx/effects", + "@ngrx/entity": "@ngrx/entity", + "@ucap/protocol-query": "@ucap/protocol-query", + "@ucap/protocol-status": "@ucap/protocol-status", "@ucap/ng-api-external": "@ucap/ng-api-external", "@ucap/ng-protocol-query": "@ucap/ng-protocol-query", + "@ucap/ng-protocol-status": "@ucap/ng-protocol-status", "@ucap/ng-store-authentication": "@ucap/ng-store-authentication" } } diff --git a/projects/store-organization/package.json b/projects/store-organization/package.json index 835c70f..a33cd82 100644 --- a/projects/store-organization/package.json +++ b/projects/store-organization/package.json @@ -1,6 +1,6 @@ { "name": "@ucap/ng-store-organization", - "version": "0.0.4", + "version": "0.0.8", "publishConfig": { "registry": "https://nexus.loafle.net/repository/npm-ucap/" }, diff --git a/projects/store-organization/src/lib/store/effects.ts b/projects/store-organization/src/lib/store/effects.ts index b907a48..3a15dbc 100644 --- a/projects/store-organization/src/lib/store/effects.ts +++ b/projects/store-organization/src/lib/store/effects.ts @@ -3,9 +3,11 @@ import { Type } from '@angular/core'; import { Effects as CommonEffects } from './common/effects'; import { Effects as CompanyEffects } from './company/effects'; import { Effects as DepartmentEffects } from './department/effects'; +import { Effects as PresenceEffects } from './presence/effects'; export const effects: Type[] = [ CommonEffects, CompanyEffects, - DepartmentEffects + DepartmentEffects, + PresenceEffects ]; diff --git a/projects/store-organization/src/lib/store/presence/actions.ts b/projects/store-organization/src/lib/store/presence/actions.ts new file mode 100644 index 0000000..ba717b6 --- /dev/null +++ b/projects/store-organization/src/lib/store/presence/actions.ts @@ -0,0 +1,58 @@ +import { createAction, props } from '@ngrx/store'; +import { + BulkInfoRequest, + StatusBulkInfo, + StatusNotification, + StatusRequest, + StatusResponse, + MessageUpdateRequest +} from '@ucap/protocol-status'; + +export const bulkInfo = createAction( + '[ucap::organization::presence] Bulk Info', + props() +); + +export const bulkInfoSuccess = createAction( + '[ucap::organization::presence] Bulk Info Success', + props<{ statusBulkInfoList: StatusBulkInfo[] }>() +); + +export const bulkInfoFailure = createAction( + '[ucap::organization::presence] Bulk Info Failure', + props<{ error: any }>() +); + +export const statusNotification = createAction( + '[ucap::organization::presence] Status Notification', + props<{ noti: StatusNotification }>() +); + +export const status = createAction( + '[ucap::organization::presence] Status', + props<{ req: StatusRequest }>() +); +export const statusSuccess = createAction( + '[ucap::organization::presence] Status Success', + props<{ + res: StatusResponse; + }>() +); +export const statusFailure = createAction( + '[ucap::organization::presence] Status Failure', + props<{ error: any }>() +); + +export const changeMyIdleCheckTime = createAction( + '[ucap::organization::presence] Change MyIdleCheckTime', + props<{ checkTime: number }>() +); + +export const messageUpdate = createAction( + '[ucap::organization::presence] status message update of Others', + props<{ req: MessageUpdateRequest }>() +); +export const messageUpdateFailure = createAction( + '[ucap::organization::presence] status message update of Others Failure', + props<{ error: any }>() +); diff --git a/projects/store-organization/src/lib/store/presence/effects.ts b/projects/store-organization/src/lib/store/presence/effects.ts new file mode 100644 index 0000000..ce88228 --- /dev/null +++ b/projects/store-organization/src/lib/store/presence/effects.ts @@ -0,0 +1,63 @@ +import { of } from 'rxjs'; +import { map, exhaustMap, catchError, tap, switchMap } from 'rxjs/operators'; + +import { Injectable } from '@angular/core'; + +import { Actions, createEffect, ofType } from '@ngrx/effects'; +import { Store } from '@ngrx/store'; + +import { + status, + statusSuccess, + statusFailure, + bulkInfo, + bulkInfoSuccess, + bulkInfoFailure +} from './actions'; +import { StatusProtocolService } from '@ucap/ng-protocol-status'; +import { StatusBulkInfo } from '@ucap/protocol-status'; + +@Injectable() +export class Effects { + bulkInfo$ = createEffect( + () => { + return this.actions$.pipe( + ofType(bulkInfo), + switchMap((req) => { + return this.statusProtocolService.bulkInfo(req).pipe( + map((res) => { + this.store.dispatch( + bulkInfoSuccess({ + statusBulkInfoList: res.statusBulkInfoList + }) + ); + }), + catchError((error) => of(bulkInfoFailure({ error }))) + ); + }) + ); + }, + { dispatch: false } + ); + + status$ = createEffect(() => + this.actions$.pipe( + ofType(status), + map((action) => action.req), + exhaustMap((req) => { + return this.statusProtocolService.status(req).pipe( + map((res) => { + return statusSuccess({ res }); + }), + catchError((error) => of(statusFailure({ error }))) + ); + }) + ) + ); + + constructor( + private actions$: Actions, + private store: Store, + private statusProtocolService: StatusProtocolService + ) {} +} diff --git a/projects/store-organization/src/lib/store/presence/reducers.ts b/projects/store-organization/src/lib/store/presence/reducers.ts new file mode 100644 index 0000000..e397f41 --- /dev/null +++ b/projects/store-organization/src/lib/store/presence/reducers.ts @@ -0,0 +1,79 @@ +import { createReducer, on } from '@ngrx/store'; +import { initialState, State, adapterStatusBulkInfo } from './state'; +import { + bulkInfoSuccess, + statusNotification, + statusSuccess, + bulkInfo +} from './actions'; +import { + StatusBulkInfo, + TerminalStatusInfo, + TerminalStatusNumber +} from '@ucap/protocol-status'; + +export const reducer = createReducer( + initialState, + on(bulkInfo, (state, action) => { + return { + ...state, + statusBulkInfoProcessing: true + } as State; + }), + + on(bulkInfoSuccess, (state, action) => { + return { + ...state, + statusBulkInfo: adapterStatusBulkInfo.upsertMany( + action.statusBulkInfoList, + { + ...state.statusBulkInfo + } + ), + statusBulkInfoProcessing: false + } as State; + }), + + on(statusNotification, (state, action) => { + const noti = action.noti; + + const statusBulkInfoState: StatusBulkInfo = { + userSeq: noti.userSeq, + conferenceStatus: noti.conferenceStatus, + imessengerStatus: noti.imessengerStatus, + mobileConferenceStatus: noti.mobileConferenceStatus, + mobileStatus: noti.mobileStatus, + pcStatus: noti.pcStatus, + phoneStatus: noti.phoneStatus, + statusMessage: noti.statusMessage, + terminalStatus: TerminalStatusInfo.Unknown, + terminalStatusNumber: TerminalStatusNumber.Unknown, + workstatus: noti.workstatus + }; + + return { + ...state, + statusBulkInfo: adapterStatusBulkInfo.upsertOne(statusBulkInfoState, { + ...state.statusBulkInfo + }), + statusBulkInfoProcessing: false + }; + }), + + on(statusSuccess, (state, action) => { + const statusBulkInfoState: StatusBulkInfo = { + ...state.statusBulkInfo.entities[action.res.SENDER_SEQ], + pcStatus: action.res.statusType, + statusMessage: action.res.statusMessage + }; + + return { + ...state, + statusBulkInfo: adapterStatusBulkInfo.updateOne( + { id: action.res.SENDER_SEQ, changes: statusBulkInfoState }, + { ...state.statusBulkInfo } + ), + statusBulkInfoProcessing: false + } as State; + }) +); diff --git a/projects/store-organization/src/lib/store/presence/state.ts b/projects/store-organization/src/lib/store/presence/state.ts new file mode 100644 index 0000000..f189b7e --- /dev/null +++ b/projects/store-organization/src/lib/store/presence/state.ts @@ -0,0 +1,56 @@ +import { Selector, createSelector } from '@ngrx/store'; +import { EntityState, createEntityAdapter } from '@ngrx/entity'; +import { StatusBulkInfo } from '@ucap/protocol-status'; + +export interface StatusBulkInfoState extends EntityState {} + +export interface State { + statusBulkInfo: StatusBulkInfoState; + statusBulkInfoProcessing: boolean; +} + +export const adapterStatusBulkInfo = createEntityAdapter({ + selectId: (statusBulkInfo) => statusBulkInfo.userSeq +}); + +const statusBulkInfoInitialState: StatusBulkInfoState = adapterStatusBulkInfo.getInitialState( + {} +); + +export const initialState: State = { + statusBulkInfo: statusBulkInfoInitialState, + statusBulkInfoProcessing: false +}; + +const { + selectAll: ngeSelectAllStatusBulkInfo, + selectEntities: ngeSelectEntitiesStatusBulkInfo +} = adapterStatusBulkInfo.getSelectors(); + +export function selectors(selector: Selector) { + const selectStatusBulkInfo = createSelector( + selector, + (state: State) => state.statusBulkInfo + ); + + return { + selectAllStatusBulkInfo: createSelector( + selectStatusBulkInfo, + ngeSelectAllStatusBulkInfo + ), + selectEntitiesStatusBulkInfo: createSelector( + selectStatusBulkInfo, + ngeSelectEntitiesStatusBulkInfo + ), + selectStatusBulkInfo: (userSeq: number) => + createSelector( + selectStatusBulkInfo, + ngeSelectEntitiesStatusBulkInfo, + (_, entities) => (!!entities ? entities[userSeq] : undefined) + ), + statusBulkInfoProcessing: createSelector( + selector, + (state: State) => state.statusBulkInfoProcessing + ) + }; +} diff --git a/projects/store-organization/src/lib/store/reducers.ts b/projects/store-organization/src/lib/store/reducers.ts index c865310..a0918f9 100644 --- a/projects/store-organization/src/lib/store/reducers.ts +++ b/projects/store-organization/src/lib/store/reducers.ts @@ -3,11 +3,13 @@ import { combineReducers, Action } from '@ngrx/store'; import { reducer as CommonReducer } from './common/reducers'; import { reducer as CompanyReducer } from './company/reducers'; import { reducer as DepartmentReducer } from './department/reducers'; +import { reducer as PresenceReducer } from './presence/reducers'; export function reducers(state: any | undefined, action: Action) { return combineReducers({ common: CommonReducer, company: CompanyReducer, - department: DepartmentReducer + department: DepartmentReducer, + presence: PresenceReducer })(state, action); } diff --git a/projects/store-organization/src/lib/store/state.ts b/projects/store-organization/src/lib/store/state.ts index e1d59f8..baff1de 100644 --- a/projects/store-organization/src/lib/store/state.ts +++ b/projects/store-organization/src/lib/store/state.ts @@ -3,6 +3,7 @@ import { createFeatureSelector, createSelector } from '@ngrx/store'; import * as CommonState from './common/state'; import * as CompanyState from './company/state'; import * as DepartmentState from './department/state'; +import * as PresenceState from './presence/state'; export const KEY_FEATURE = 'organization'; @@ -10,6 +11,7 @@ export interface State { common: CommonState.State; company: CompanyState.State; department: DepartmentState.State; + presence: PresenceState.State; } export const Selector = createFeatureSelector(KEY_FEATURE); @@ -25,3 +27,7 @@ export const CompanySelector = CompanyState.selectors( export const DepartmentSelector = DepartmentState.selectors( createSelector(Selector, (state: State) => state.department) ); + +export const PresenceSelector = PresenceState.selectors( + createSelector(Selector, (state: State) => state.presence) +); diff --git a/projects/store-organization/src/public-api.ts b/projects/store-organization/src/public-api.ts index 4286565..bf49c75 100644 --- a/projects/store-organization/src/public-api.ts +++ b/projects/store-organization/src/public-api.ts @@ -5,10 +5,11 @@ import * as CommonActions from './lib/store/common/actions'; import * as CompanyActions from './lib/store/company/actions'; import * as DepartmentActions from './lib/store/department/actions'; +import * as PresenceActions from './lib/store/presence/actions'; export * from './lib/config/module-config'; -export { CommonActions, CompanyActions, DepartmentActions }; +export { CommonActions, CompanyActions, DepartmentActions, PresenceActions }; export * from './lib/store/state'; diff --git a/projects/ui-authentication/package.json b/projects/ui-authentication/package.json index 35fc791..7b0f7f5 100644 --- a/projects/ui-authentication/package.json +++ b/projects/ui-authentication/package.json @@ -1,6 +1,6 @@ { "name": "@ucap/ng-ui-authentication", - "version": "0.0.19", + "version": "0.0.20", "publishConfig": { "registry": "https://nexus.loafle.net/repository/npm-ucap/" }, @@ -10,6 +10,7 @@ "@angular/core": "^9.0.2", "@angular/material": "^9.0.0", "@ucap/core": "~0.0.1", + "@ucap/uc-scss": "~0.0.1", "@ucap/ng-i18n": "~0.0.1", "@ucap/ng-ui": "~0.0.1", "tslib": "^1.10.0" diff --git a/projects/ui-authentication/src/lib/components/login.component.html b/projects/ui-authentication/src/lib/components/login.component.html index f04f718..b40cc05 100644 --- a/projects/ui-authentication/src/lib/components/login.component.html +++ b/projects/ui-authentication/src/lib/components/login.component.html @@ -1,29 +1,31 @@ -