diff --git a/package-lock.json b/package-lock.json index 9953b121c..293575fcf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -58,7 +58,7 @@ "zone.js": "~0.11.6" }, "devDependencies": { - "@angular-devkit/build-angular": "14.2.6", + "@angular-devkit/build-angular": "^14.2.10", "@angular-eslint/builder": "14.0.2", "@angular-eslint/eslint-plugin": "14.0.2", "@angular-eslint/eslint-plugin-template": "14.0.2", @@ -160,15 +160,15 @@ "dev": true }, "node_modules/@angular-devkit/build-angular": { - "version": "14.2.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-14.2.6.tgz", - "integrity": "sha512-XtaUwb3aZ8S0vl0y9bmbdFOH0KQCQ778twFH+ZfHW2BcPYtQz2Cy2rcVKXBQ850RyC0GxgMPfco6OGQndPpizg==", + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-14.2.10.tgz", + "integrity": "sha512-VCeZAyq4uPCJukKInaSiD4i/GgxgcU4jFlLFQtoYNmaBS4xbPOymL19forRIihiV0dwNEa2L694vRTAPMBxIfw==", "dev": true, "dependencies": { "@ampproject/remapping": "2.2.0", - "@angular-devkit/architect": "0.1402.6", - "@angular-devkit/build-webpack": "0.1402.6", - "@angular-devkit/core": "14.2.6", + "@angular-devkit/architect": "0.1402.10", + "@angular-devkit/build-webpack": "0.1402.10", + "@angular-devkit/core": "14.2.10", "@babel/core": "7.18.10", "@babel/generator": "7.18.12", "@babel/helper-annotate-as-pure": "7.18.6", @@ -179,7 +179,7 @@ "@babel/runtime": "7.18.9", "@babel/template": "7.18.10", "@discoveryjs/json-ext": "0.5.7", - "@ngtools/webpack": "14.2.6", + "@ngtools/webpack": "14.2.10", "ansi-colors": "4.1.3", "babel-loader": "8.2.5", "babel-plugin-istanbul": "6.1.1", @@ -197,7 +197,7 @@ "less": "4.1.3", "less-loader": "11.0.0", "license-webpack-plugin": "4.0.2", - "loader-utils": "3.2.0", + "loader-utils": "3.2.1", "mini-css-extract-plugin": "2.6.1", "minimatch": "5.1.0", "open": "8.4.0", @@ -268,12 +268,12 @@ } }, "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/architect": { - "version": "0.1402.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.6.tgz", - "integrity": "sha512-qTmPBD7fBXBtlSapGLUEcJvRuL/O556zCFFpH3kSlzPNTYxi2falBjGY+4aG+078RXT1vVZtFsvRTart6VbhAg==", + "version": "0.1402.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.10.tgz", + "integrity": "sha512-/6YmPrgataj1jD2Uqd1ED+CG4DaZGacoeZd/89hH7hF76Nno8K18DrSOqJAEmDnOWegpSRGVLd0qP09IHmaG5w==", "dev": true, "dependencies": { - "@angular-devkit/core": "14.2.6", + "@angular-devkit/core": "14.2.10", "rxjs": "6.6.7" }, "engines": { @@ -283,9 +283,9 @@ } }, "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/core": { - "version": "14.2.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.6.tgz", - "integrity": "sha512-qtRSdRm/h7C3ya04PJTDgQXV6mM8Y4RakANX1GTSXetCf9AVSxg74NJX76DWUgiHT4JiPYnJgJU6Hr/L0H6JOQ==", + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.10.tgz", + "integrity": "sha512-K4AO7mROTdbhQ7chtyQd6oPwmuL+BPUh+wn6Aq1qrmYJK4UZYFOPp8fi/Ehs8meCEeywtrssOPfrOE4Gsre9dg==", "dev": true, "dependencies": { "ajv": "8.11.0", @@ -351,12 +351,12 @@ } }, "node_modules/@angular-devkit/build-webpack": { - "version": "0.1402.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1402.6.tgz", - "integrity": "sha512-gKsDxQ9pze0N1qDM0kdM4FfwpkjSOb0bQzqjZi7wTfrh/WGIQMCjG9CRwWT+Z289ZKaTpcQDPsDtOSo5QpKNDg==", + "version": "0.1402.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1402.10.tgz", + "integrity": "sha512-h+2MaSY7QSvoJ3R+Hvin21jVCfPGOTLdASIUk4Jmq6J3y5BSku3KSSaV8dWoBOBkFCwQyPQMRjiHoHKLpC1K7g==", "dev": true, "dependencies": { - "@angular-devkit/architect": "0.1402.6", + "@angular-devkit/architect": "0.1402.10", "rxjs": "6.6.7" }, "engines": { @@ -370,12 +370,12 @@ } }, "node_modules/@angular-devkit/build-webpack/node_modules/@angular-devkit/architect": { - "version": "0.1402.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.6.tgz", - "integrity": "sha512-qTmPBD7fBXBtlSapGLUEcJvRuL/O556zCFFpH3kSlzPNTYxi2falBjGY+4aG+078RXT1vVZtFsvRTart6VbhAg==", + "version": "0.1402.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.10.tgz", + "integrity": "sha512-/6YmPrgataj1jD2Uqd1ED+CG4DaZGacoeZd/89hH7hF76Nno8K18DrSOqJAEmDnOWegpSRGVLd0qP09IHmaG5w==", "dev": true, "dependencies": { - "@angular-devkit/core": "14.2.6", + "@angular-devkit/core": "14.2.10", "rxjs": "6.6.7" }, "engines": { @@ -385,9 +385,9 @@ } }, "node_modules/@angular-devkit/build-webpack/node_modules/@angular-devkit/core": { - "version": "14.2.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.6.tgz", - "integrity": "sha512-qtRSdRm/h7C3ya04PJTDgQXV6mM8Y4RakANX1GTSXetCf9AVSxg74NJX76DWUgiHT4JiPYnJgJU6Hr/L0H6JOQ==", + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.10.tgz", + "integrity": "sha512-K4AO7mROTdbhQ7chtyQd6oPwmuL+BPUh+wn6Aq1qrmYJK4UZYFOPp8fi/Ehs8meCEeywtrssOPfrOE4Gsre9dg==", "dev": true, "dependencies": { "ajv": "8.11.0", @@ -3303,9 +3303,9 @@ } }, "node_modules/@ngtools/webpack": { - "version": "14.2.6", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-14.2.6.tgz", - "integrity": "sha512-HdfoHLGPzyP135BOlvTQcpeWisVfiH0u40YNTBVK3QAsrLnY17e2QG5BWBOrVYipRu1975cZtTC9rPjcCY8aLQ==", + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-14.2.10.tgz", + "integrity": "sha512-sLHapZLVub6mEz5b19tf1VfIV1w3tYfg7FNPLeni79aldxu1FbP1v2WmiFAnMzrswqyK0bhTtxrl+Z/CLKqyoQ==", "dev": true, "engines": { "node": "^14.15.0 || >=16.10.0", @@ -4115,9 +4115,9 @@ "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==" }, "node_modules/@types/ws": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", - "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.4.tgz", + "integrity": "sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==", "dev": true, "dependencies": { "@types/node": "*" @@ -5327,9 +5327,9 @@ } }, "node_modules/app-root-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.0.0.tgz", - "integrity": "sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz", + "integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==", "dev": true, "engines": { "node": ">= 6.0.0" @@ -5837,9 +5837,9 @@ } }, "node_modules/bonjour-service": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.0.14.tgz", - "integrity": "sha512-HIMbgLnk1Vqvs6B4Wq5ep7mxvj9sGz5d1JJyDNSGNIdA/w2MCz6GTjWTdjqOJV1bEPj+6IkxDvWNFKEBxNt4kQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.0.tgz", + "integrity": "sha512-LVRinRB3k1/K0XzZ2p58COnWvkQknIY6sf0zF2rpErvcJXpMBttEPQSxK+HEXSS9VmpZlDoDnQWv8ftJT20B0Q==", "dev": true, "dependencies": { "array-flatten": "^2.1.2", @@ -12226,9 +12226,9 @@ } }, "node_modules/loader-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.0.tgz", - "integrity": "sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", + "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", "dev": true, "engines": { "node": ">= 12.13.0" @@ -12604,9 +12604,9 @@ } }, "node_modules/memfs": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.7.tgz", - "integrity": "sha512-ygaiUSNalBX85388uskeCyhSAoOSgzBbtVCr9jA2RROssFL9Q19/ZXFqS+2Th2sr1ewNIWgFdLzLC3Yl1Zv+lw==", + "version": "3.4.13", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.13.tgz", + "integrity": "sha512-omTM41g3Skpvx5dSYeZIbXKcXoAVc/AoMNwn9TKx++L/gaen/+4TTttmu8ZSch5vfVJ8uJvGbroTsIlslRg6lg==", "dev": true, "dependencies": { "fs-monkey": "^1.0.3" @@ -19512,15 +19512,15 @@ } }, "@angular-devkit/build-angular": { - "version": "14.2.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-14.2.6.tgz", - "integrity": "sha512-XtaUwb3aZ8S0vl0y9bmbdFOH0KQCQ778twFH+ZfHW2BcPYtQz2Cy2rcVKXBQ850RyC0GxgMPfco6OGQndPpizg==", + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-14.2.10.tgz", + "integrity": "sha512-VCeZAyq4uPCJukKInaSiD4i/GgxgcU4jFlLFQtoYNmaBS4xbPOymL19forRIihiV0dwNEa2L694vRTAPMBxIfw==", "dev": true, "requires": { "@ampproject/remapping": "2.2.0", - "@angular-devkit/architect": "0.1402.6", - "@angular-devkit/build-webpack": "0.1402.6", - "@angular-devkit/core": "14.2.6", + "@angular-devkit/architect": "0.1402.10", + "@angular-devkit/build-webpack": "0.1402.10", + "@angular-devkit/core": "14.2.10", "@babel/core": "7.18.10", "@babel/generator": "7.18.12", "@babel/helper-annotate-as-pure": "7.18.6", @@ -19531,7 +19531,7 @@ "@babel/runtime": "7.18.9", "@babel/template": "7.18.10", "@discoveryjs/json-ext": "0.5.7", - "@ngtools/webpack": "14.2.6", + "@ngtools/webpack": "14.2.10", "ansi-colors": "4.1.3", "babel-loader": "8.2.5", "babel-plugin-istanbul": "6.1.1", @@ -19550,7 +19550,7 @@ "less": "4.1.3", "less-loader": "11.0.0", "license-webpack-plugin": "4.0.2", - "loader-utils": "3.2.0", + "loader-utils": "3.2.1", "mini-css-extract-plugin": "2.6.1", "minimatch": "5.1.0", "open": "8.4.0", @@ -19583,19 +19583,19 @@ }, "dependencies": { "@angular-devkit/architect": { - "version": "0.1402.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.6.tgz", - "integrity": "sha512-qTmPBD7fBXBtlSapGLUEcJvRuL/O556zCFFpH3kSlzPNTYxi2falBjGY+4aG+078RXT1vVZtFsvRTart6VbhAg==", + "version": "0.1402.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.10.tgz", + "integrity": "sha512-/6YmPrgataj1jD2Uqd1ED+CG4DaZGacoeZd/89hH7hF76Nno8K18DrSOqJAEmDnOWegpSRGVLd0qP09IHmaG5w==", "dev": true, "requires": { - "@angular-devkit/core": "14.2.6", + "@angular-devkit/core": "14.2.10", "rxjs": "6.6.7" } }, "@angular-devkit/core": { - "version": "14.2.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.6.tgz", - "integrity": "sha512-qtRSdRm/h7C3ya04PJTDgQXV6mM8Y4RakANX1GTSXetCf9AVSxg74NJX76DWUgiHT4JiPYnJgJU6Hr/L0H6JOQ==", + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.10.tgz", + "integrity": "sha512-K4AO7mROTdbhQ7chtyQd6oPwmuL+BPUh+wn6Aq1qrmYJK4UZYFOPp8fi/Ehs8meCEeywtrssOPfrOE4Gsre9dg==", "dev": true, "requires": { "ajv": "8.11.0", @@ -19643,29 +19643,29 @@ } }, "@angular-devkit/build-webpack": { - "version": "0.1402.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1402.6.tgz", - "integrity": "sha512-gKsDxQ9pze0N1qDM0kdM4FfwpkjSOb0bQzqjZi7wTfrh/WGIQMCjG9CRwWT+Z289ZKaTpcQDPsDtOSo5QpKNDg==", + "version": "0.1402.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1402.10.tgz", + "integrity": "sha512-h+2MaSY7QSvoJ3R+Hvin21jVCfPGOTLdASIUk4Jmq6J3y5BSku3KSSaV8dWoBOBkFCwQyPQMRjiHoHKLpC1K7g==", "dev": true, "requires": { - "@angular-devkit/architect": "0.1402.6", + "@angular-devkit/architect": "0.1402.10", "rxjs": "6.6.7" }, "dependencies": { "@angular-devkit/architect": { - "version": "0.1402.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.6.tgz", - "integrity": "sha512-qTmPBD7fBXBtlSapGLUEcJvRuL/O556zCFFpH3kSlzPNTYxi2falBjGY+4aG+078RXT1vVZtFsvRTart6VbhAg==", + "version": "0.1402.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.10.tgz", + "integrity": "sha512-/6YmPrgataj1jD2Uqd1ED+CG4DaZGacoeZd/89hH7hF76Nno8K18DrSOqJAEmDnOWegpSRGVLd0qP09IHmaG5w==", "dev": true, "requires": { - "@angular-devkit/core": "14.2.6", + "@angular-devkit/core": "14.2.10", "rxjs": "6.6.7" } }, "@angular-devkit/core": { - "version": "14.2.6", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.6.tgz", - "integrity": "sha512-qtRSdRm/h7C3ya04PJTDgQXV6mM8Y4RakANX1GTSXetCf9AVSxg74NJX76DWUgiHT4JiPYnJgJU6Hr/L0H6JOQ==", + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.10.tgz", + "integrity": "sha512-K4AO7mROTdbhQ7chtyQd6oPwmuL+BPUh+wn6Aq1qrmYJK4UZYFOPp8fi/Ehs8meCEeywtrssOPfrOE4Gsre9dg==", "dev": true, "requires": { "ajv": "8.11.0", @@ -21641,9 +21641,9 @@ } }, "@ngtools/webpack": { - "version": "14.2.6", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-14.2.6.tgz", - "integrity": "sha512-HdfoHLGPzyP135BOlvTQcpeWisVfiH0u40YNTBVK3QAsrLnY17e2QG5BWBOrVYipRu1975cZtTC9rPjcCY8aLQ==", + "version": "14.2.10", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-14.2.10.tgz", + "integrity": "sha512-sLHapZLVub6mEz5b19tf1VfIV1w3tYfg7FNPLeni79aldxu1FbP1v2WmiFAnMzrswqyK0bhTtxrl+Z/CLKqyoQ==", "dev": true, "requires": {} }, @@ -22311,9 +22311,9 @@ "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==" }, "@types/ws": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", - "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.4.tgz", + "integrity": "sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==", "dev": true, "requires": { "@types/node": "*" @@ -23200,9 +23200,9 @@ } }, "app-root-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.0.0.tgz", - "integrity": "sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz", + "integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==", "dev": true }, "aproba": { @@ -23581,9 +23581,9 @@ } }, "bonjour-service": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.0.14.tgz", - "integrity": "sha512-HIMbgLnk1Vqvs6B4Wq5ep7mxvj9sGz5d1JJyDNSGNIdA/w2MCz6GTjWTdjqOJV1bEPj+6IkxDvWNFKEBxNt4kQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.0.tgz", + "integrity": "sha512-LVRinRB3k1/K0XzZ2p58COnWvkQknIY6sf0zF2rpErvcJXpMBttEPQSxK+HEXSS9VmpZlDoDnQWv8ftJT20B0Q==", "dev": true, "requires": { "array-flatten": "^2.1.2", @@ -28346,9 +28346,9 @@ "dev": true }, "loader-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.0.tgz", - "integrity": "sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", + "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", "dev": true }, "localtunnel": { @@ -28644,9 +28644,9 @@ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" }, "memfs": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.7.tgz", - "integrity": "sha512-ygaiUSNalBX85388uskeCyhSAoOSgzBbtVCr9jA2RROssFL9Q19/ZXFqS+2Th2sr1ewNIWgFdLzLC3Yl1Zv+lw==", + "version": "3.4.13", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.13.tgz", + "integrity": "sha512-omTM41g3Skpvx5dSYeZIbXKcXoAVc/AoMNwn9TKx++L/gaen/+4TTttmu8ZSch5vfVJ8uJvGbroTsIlslRg6lg==", "dev": true, "requires": { "fs-monkey": "^1.0.3" diff --git a/package.json b/package.json index 9b97c81f1..e911e7b72 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,7 @@ "zone.js": "~0.11.6" }, "devDependencies": { - "@angular-devkit/build-angular": "14.2.6", + "@angular-devkit/build-angular": "^14.2.10", "@angular-eslint/builder": "14.0.2", "@angular-eslint/eslint-plugin": "14.0.2", "@angular-eslint/eslint-plugin-template": "14.0.2", diff --git a/src/app/components/harvest/components/inputs/site-selector.component.ts b/src/app/components/harvest/components/inputs/site-selector.component.ts index 37b9633fb..c2cfeec0c 100644 --- a/src/app/components/harvest/components/inputs/site-selector.component.ts +++ b/src/app/components/harvest/components/inputs/site-selector.component.ts @@ -33,7 +33,11 @@ import { defaultDebounceTime } from "src/app/app.helper"; template: `
- {{ site.name }} + {{ site.name }}
- +
@@ -61,7 +62,7 @@ import { Project } from "@models/Project"; @@ -71,7 +72,8 @@ import { Project } from "@models/Project";
@@ -80,7 +82,7 @@ import { Project } from "@models/Project";
@@ -138,6 +140,22 @@ export class FolderRowComponent { return this.row.mapping; } + /** + * The row mapping and the view mapping diverge because there are server side rules that define how mappings are inherited + * These mappings however, should not be reflected in the models, but should be displayed to the user as inherited + */ + public get viewMapping(): HarvestMapping { + let currentFolder = this.row; + + // some folders such as the root folder do not have a parent folder. In this case, the current folder will be set to undefined, and + // it can be concured that there is no mapping anywhere in the hierarchy + while (!!currentFolder && !currentFolder?.mapping) { + currentFolder = currentFolder?.parentFolder; + } + + return currentFolder?.mapping; + } + public get harvestItem(): HarvestItem { return this.row.harvestItem; } @@ -146,18 +164,20 @@ export class FolderRowComponent { return this.harvestItem.report; } + public get hasHarvestItems(): boolean { + return !this.mapping && !(this.row.isRoot && !+this.row.harvestItem); + } + public constructor(private injector: Injector) {} - public createMapping(row: MetaReviewFolder): void { + public createMapping(row: MetaReviewFolder, data?: Partial): void { const mapping = new HarvestMapping( { - // Root folder is not a harvest item, so root folder row does not have - // a harvest item - path: row.isRoot ? row.path : row.harvestItem.path, - recursive: true, - siteId: null, - utcOffset: null, - }, + path: this.row.isRoot ? this.row.path : this.row.harvestItem.path, + recursive: data?.recursive ?? true, + siteId: data?.siteId ?? null, + utcOffset: data?.utcOffset ?? null, + } as HarvestMapping, this.injector ); row.mapping = mapping; @@ -165,16 +185,28 @@ export class FolderRowComponent { } public setSite(mapping: HarvestMapping, siteId: number): void { + if (!mapping) { + this.createMapping(this.row, this.viewMapping); + } + mapping.siteId = siteId; this.mappingsChange.emit(); } public setOffset(mapping: HarvestMapping, offset: string): void { + if (!mapping) { + this.createMapping(this.row, this.viewMapping); + } + mapping.utcOffset = offset; this.mappingsChange.emit(); } public setIsRecursive(mapping: HarvestMapping, isRecursive: boolean): void { + if (!mapping) { + this.createMapping(this.row, this.viewMapping); + } + mapping.recursive = isRecursive; this.mappingsChange.emit(); } diff --git a/src/app/components/harvest/screens/metadata-review/metadata-review.component.html b/src/app/components/harvest/screens/metadata-review/metadata-review.component.html index 766d67908..a9034ae6f 100644 --- a/src/app/components/harvest/screens/metadata-review/metadata-review.component.html +++ b/src/app/components/harvest/screens/metadata-review/metadata-review.component.html @@ -86,11 +86,11 @@

Review

@@ -130,7 +130,7 @@

Review

- +

Are you sure you wish to return to the uploading stage?

diff --git a/src/app/components/harvest/screens/metadata-review/metadata-review.component.spec.ts b/src/app/components/harvest/screens/metadata-review/metadata-review.component.spec.ts index 14286342e..d20abda21 100644 --- a/src/app/components/harvest/screens/metadata-review/metadata-review.component.spec.ts +++ b/src/app/components/harvest/screens/metadata-review/metadata-review.component.spec.ts @@ -63,7 +63,7 @@ describe("MetadataReviewComponent", () => { MockProvider(HarvestStagesService, { project: defaultProject, harvest: defaultHarvest, - transition: (_stage: HarvestStatus) => {} + transition: (_stage: HarvestStatus) => { } }), ], imports: [MockBawApiModule, SharedModule], @@ -100,6 +100,12 @@ describe("MetadataReviewComponent", () => { const getModalCancelButton = (): HTMLButtonElement => spec.query("baw-harvest-confirmation-modal #cancel-btn", { root: true }); + const getHarvestMappingRecursiveCheckbox = (index: number): HTMLInputElement => + spec.queryAll("#undefined-checkbox", { root: true })[index] + + const getEditMappingButton = (index: number): HTMLButtonElement => + spec.queryAll(".btn-outline-primary", { root: true })[index]; + function getAbortButton(): HTMLButtonElement { return spec.debugElement.query( (el) => el.nativeElement.innerText === "Abort" @@ -127,13 +133,13 @@ describe("MetadataReviewComponent", () => { } function clickEditMappingButton(index: number): void { - const mappingEditButton = spec.queryAll(".btn-outline-primary", { root: true })[index]; + const mappingEditButton = getEditMappingButton(index); mappingEditButton.click(); updateComponent(); } function toggleHarvestMappingRecursive(index: number): void { - const mappingRecursiveCheckbox = spec.queryAll("#undefined-checkbox", { root: true })[index]; + const mappingRecursiveCheckbox = getHarvestMappingRecursiveCheckbox(index); mappingRecursiveCheckbox.click(); updateComponent(); } @@ -141,14 +147,22 @@ describe("MetadataReviewComponent", () => { beforeEach(() => { defaultProject = new Project(generateProject()); defaultProject.addMetadata(generateProjectMeta({})); - defaultHarvest = new Harvest(generateHarvest({ status: "metadataReview" })); + + // by default, harvests will not have any inherited mappings + // to set inherited mappings, set the mappings attribute in the default harvest before calling `setup()` + defaultHarvest = new Harvest(generateHarvest({ + status: "metadataReview", + mappings: [] + })); }); - afterEach(() => { + afterEach(fakeAsync(() => { // dismiss all bootstrap modals, so if a test fails // it doesn't impact future tests by using a stale modal modalService.dismissAll(); - }); + flush(); + discardPeriodicTasks(); + })); it("should create", () => { setup(); @@ -165,8 +179,6 @@ describe("MetadataReviewComponent", () => { tick(); expect(stages.transition).not.toHaveBeenCalled(); - discardPeriodicTasks(); - flush(); })); it("should transition the Harvest to 'complete' when the 'Abort Harvest' button is clicked in abort warning modal", fakeAsync(() => { @@ -179,18 +191,11 @@ describe("MetadataReviewComponent", () => { tick(); expect(stages.transition).toHaveBeenCalledWith("complete"); - discardPeriodicTasks(); - flush(); })); it("should have persistent mappings when folders close", fakeAsync(() => { setup(); - defaultHarvest = new Harvest({ - ...defaultHarvest, - mappings: [] - }); - // when a folder item is clicked, the getHarvestItems() method returns the sub folders & items included in the folder // therefore, by mocking getHarvestItems() and resolving to custom files, we can control the sub-folders & items // that will be displayed when a folder in the directory tree is clicked @@ -265,9 +270,6 @@ describe("MetadataReviewComponent", () => { clickEditMappingButton(4); toggleHarvestMappingRecursive(0); expect(harvestService.updateMappings).toHaveBeenCalledTimes(2); - - flush(); - discardPeriodicTasks(); })); it("should retain mappings assigned in previous stages after change in mapping through interface", fakeAsync(() => { @@ -316,7 +318,7 @@ describe("MetadataReviewComponent", () => { utcInputDropdown.dispatchEvent(new Event("change")); updateComponent(); - const expectedMappings: HarvestMapping[] = [ + const expectedMappings: HarvestMapping[] = [ new HarvestMapping({ path: "A", recursive: true, @@ -350,9 +352,52 @@ describe("MetadataReviewComponent", () => { expect(harvestService.updateMappings).toHaveBeenCalledTimes(1); expect(JSON.stringify(spec.component.harvest.mappings)).toEqual(JSON.stringify(expectedMappings)); - - flush(); - discardPeriodicTasks(); })); + it("should retain inherited mappings when a child harvest is rendered", fakeAsync(() => { + setup(); + const mockParentFolderName = "mockParentFolder"; + const mockSubFolderName = `${mockParentFolderName}/mockSubFolder`; + const rootFolderStructure = folderStructureFactory([mockParentFolderName]); + const subFolderStructure = folderStructureFactory([mockSubFolderName]); + + // define that there is a folder "mockSubFolder" underneath the parent folder + const getHarvestItemsSpy = spyOn(stages, "getHarvestItems").and.resolveTo(rootFolderStructure); + updateComponent(); + + // assign mappings to the root folder (toggle recursive) + // These mappings should be inherited and retained to the child folder when the root folder is opened + clickEditMappingButton(0); + toggleHarvestMappingRecursive(0); + updateComponent(); + + // open the root folder to render the sub folder "mockSubFolder" + getHarvestItemsSpy.and.callThrough(); + getHarvestItemsSpy.and.resolveTo(subFolderStructure); + clickFolder(mockParentFolderName); + + // assert that the mapping of the root folder can also be seen on the sub folder "mockSubFolder" + // assert that the recursive mapping is disabled visually + const subFolderRowNumber = 1; + const parentMappingModel = new HarvestMapping({ + path: mockParentFolderName, + recursive: false, + siteId: null, + utcOffset: null, + }); + + // the sub and parent mappings should be identical with the exception of the path attribute + const expectedModelMappings: HarvestMapping[] = [ + parentMappingModel, + new HarvestMapping({ + ...parentMappingModel, + path: mockSubFolderName + }), + ]; + + expect(getHarvestMappingRecursiveCheckbox(subFolderRowNumber).checked).toBeFalse(); + + // assert that the recursive mapping is disabled in the model + expect(JSON.stringify(spec.component.harvest.mappings)).toEqual(JSON.stringify(expectedModelMappings)); + })); }); diff --git a/src/app/components/harvest/screens/metadata-review/metadata-review.component.ts b/src/app/components/harvest/screens/metadata-review/metadata-review.component.ts index a4626e0f5..9db86e49c 100644 --- a/src/app/components/harvest/screens/metadata-review/metadata-review.component.ts +++ b/src/app/components/harvest/screens/metadata-review/metadata-review.component.ts @@ -276,7 +276,7 @@ export class MetadataReviewComponent this.hasUnsavedChanges = true; this.harvestApi .updateMappings(this.harvest, adjustedMappings) - // eslint-disable-next-line rxjs-angular/prefer-takeuntil + .pipe(takeUntil(this.unsubscribe)) .subscribe({ next: (harvest: Harvest): void => { this.stages.setHarvest(harvest); diff --git a/src/app/components/harvest/widgets/validations.component.html b/src/app/components/harvest/widgets/validations.component.html index de7e76cce..93f2f6d66 100644 --- a/src/app/components/harvest/widgets/validations.component.html +++ b/src/app/components/harvest/widgets/validations.component.html @@ -6,6 +6,8 @@

You can open and close folders by clicking on them.

+

You don't have to change anything for files that have no problems.

+
@@ -27,13 +29,13 @@

Some files have missing dates. To fix, go back to the upload stage, and ensure their filenames include a - date. + date.

Some files have dates in the future. To fix, go back to the upload stage, and - rename the files.

@@ -70,12 +72,24 @@
it was an upload error. If this was an upload error, re-upload it.

-

- Some files are duplicates of previously uploaded files indicating an - accidental upload. You should go back to the upload stage and delete the - duplicates.
If you have duplicates in Site A and in - Site B we'll reject both. We don't know for sure which site they're - meant to be in. +

+ Some files in the current upload are duplicate files from a previous + uploaded indicating an accidental upload. You can go back and + change the files + to delete the duplicates duplicates. +

+ +

+ Some files in the current upload are duplicates of each other indicating + an accidental upload. You can go back and + change the files + to delete the duplicates duplicates.
If you have duplicates in + Site A and in Site B we'll reject both. We don't know for + sure which site they're meant to be in.

+ + + +

Are you sure you wish to return to the uploading stage?

+
+
diff --git a/src/app/components/harvest/widgets/validations.component.ts b/src/app/components/harvest/widgets/validations.component.ts index 25d93a520..600df40e3 100644 --- a/src/app/components/harvest/widgets/validations.component.ts +++ b/src/app/components/harvest/widgets/validations.component.ts @@ -5,6 +5,7 @@ import { WidgetMenuItem } from "@menu/widgetItem"; import { ValidationName } from "@models/HarvestItem"; import { ConfigService } from "@services/config/config.service"; import { map, Observable, startWith } from "rxjs"; +import { NgbModal } from "@ng-bootstrap/ng-bootstrap"; import { metaReviewIcons } from "../screens/metadata-review/metadata-review.component"; import { HarvestStagesService } from "../services/harvest-stages.service"; @@ -30,7 +31,8 @@ export class ValidationsWidgetComponent implements WidgetComponent, OnInit { public constructor( private stages: HarvestStagesService, - private config: ConfigService + private config: ConfigService, + public modals: NgbModal, ) {} public ngOnInit(): void { @@ -40,6 +42,15 @@ export class ValidationsWidgetComponent implements WidgetComponent, OnInit { ); } + public async upload(template: any): Promise { + const ref = this.modals.open(template); + const success = await ref.result.catch((_) => false); + + if (success) { + this.stages.transition("uploading"); + } + } + public hasError(error: ValidationName): boolean { return this.stages.harvestItemErrors.has(error); } diff --git a/src/app/styles/_media-mixin.scss b/src/app/styles/_media-mixin.scss index 39eb252e4..7a58e40ae 100644 --- a/src/app/styles/_media-mixin.scss +++ b/src/app/styles/_media-mixin.scss @@ -1,7 +1,7 @@ @use "sass:map"; -@import "~include-media/dist/include-media"; -@import "~bootstrap/scss/functions"; -@import "~bootstrap/scss/variables"; +@import "include-media/dist/include-media"; +@import "bootstrap/scss/functions"; +@import "bootstrap/scss/variables"; // These breakpoints must exist for include-media to function $breakpoints: ( diff --git a/src/app/styles/_ngx-datatable.scss b/src/app/styles/_ngx-datatable.scss index ac42f1391..1522be4fd 100644 --- a/src/app/styles/_ngx-datatable.scss +++ b/src/app/styles/_ngx-datatable.scss @@ -1,6 +1,6 @@ -@import "~@swimlane/ngx-datatable/index.css"; -@import "~@swimlane/ngx-datatable/themes/bootstrap.scss"; -@import "~@swimlane/ngx-datatable/assets/icons.css"; +@import "@swimlane/ngx-datatable/index.css"; +@import "@swimlane/ngx-datatable/themes/bootstrap.scss"; +@import "@swimlane/ngx-datatable/assets/icons.css"; $ngx-datatable-selected-active-background: lightgrey; $ngx-datatable-selected-active-background-hover: rgba(lightgrey, 0.5); diff --git a/src/app/styles/bootstrap/_index.scss b/src/app/styles/bootstrap/_index.scss index 0c8548ae3..6a13d7803 100644 --- a/src/app/styles/bootstrap/_index.scss +++ b/src/app/styles/bootstrap/_index.scss @@ -1,7 +1,7 @@ @import "root"; @import "variables"; -@import "~bootstrap/scss/bootstrap.scss"; +@import "bootstrap/scss/bootstrap.scss"; @import "components/index"; @import "utilities/index"; diff --git a/src/app/styles/bootstrap/_root.scss b/src/app/styles/bootstrap/_root.scss index 05719af83..d696494be 100644 --- a/src/app/styles/bootstrap/_root.scss +++ b/src/app/styles/bootstrap/_root.scss @@ -1,5 +1,5 @@ -@import "~bootstrap/scss/functions"; -@import "~bootstrap/scss/variables"; +@import "bootstrap/scss/functions"; +@import "bootstrap/scss/variables"; @import "../functions"; :root { diff --git a/src/styles.scss b/src/styles.scss index ccab19cb3..7a99ad440 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -3,8 +3,8 @@ @import "images"; @import "functions"; @import "callout"; -@import "~@fortawesome/fontawesome-svg-core/styles.css"; -@import "~ngx-toastr/toastr"; +@import "@fortawesome/fontawesome-svg-core/styles.css"; +@import "ngx-toastr/toastr"; /* Global css variables */ :root {